Передача числа, Number.prototype.format

Я видел эту функцию форматирования упоминается на нескольких сайтах, но ни на одном из них нет явного примера того, как передать число в функцию.

Я пробовал '12345'.format('0.00'), который, как мне кажется, должен быть написан, но выдает ошибку, что объект не поддерживает свойство или метод. Я также пробовал Number('12345').format('0.00'); var num = '12345' // num.format('0.00'); format('0.00','12345') и даже пытались использовать числа вместо строк 12345.format(0.00). Я пропустил что-то действительно очевидное здесь?

Включена копия функции для справки, поэтому вам не нужно заходить на сайт (все недостающие элементы заполнены).

/**
 * I ♥ Google
 */
String.prototype.stripNonNumeric = function() {
    var str = this + '';
    var rgx = /^\d|\.|-$/;
    var out = '';
    for( var i = 0; i < str.length; i++ ) {
        if( rgx.test( str.charAt(i) ) ) {
            if( !( ( str.charAt(i) == '.' && out.indexOf( '.' ) != -1 ) ||
            ( str.charAt(i) == '-' && out.length != 0 ) ) ) {
                out += str.charAt(i);
            }
        }
    }
    return out;
};

/**
 * Formats the number according to the 'format' string; adherses to the american number standard where a comma is inserted after every 3 digits.
 *  note: there should be only 1 contiguous number in the format, where a number consists of digits, period, and commas
 *        any other characters can be wrapped around this number, including '$', '%', or text
 *        examples (123456.789):
 *          '0' - (123456) show only digits, no precision
 *          '0.00' - (123456.78) show only digits, 2 precision
 *          '0.0000' - (123456.7890) show only digits, 4 precision
 *          '0,000' - (123,456) show comma and digits, no precision
 *          '0,000.00' - (123,456.78) show comma and digits, 2 precision
 *          '0,0.00' - (123,456.78) shortcut method, show comma and digits, 2 precision
 *
 * @method format
 * @param format {string} the way you would like to format this text
 * @return {string} the formatted number
 * @public
 */
Number.prototype.format = function(format) {
    if (!(typeof format == "string")) {return '';} // sanity check

    var hasComma = -1 < format.indexOf(','),
        psplit = format.stripNonNumeric().split('.'),
        that = this;

    // compute precision
    if (1 < psplit.length) {
        // fix number precision
        that = that.toFixed(psplit[1].length);
    }
    // error: too many periods
    else if (2 < psplit.length) {
        throw('NumberFormatException: invalid format, formats should have no more than 1 period: ' + format);
    }
    // remove precision
    else {
        that = that.toFixed(0);
    }

    // get the string now that precision is correct
    var fnum = that.toString();

    // format has comma, then compute commas
    if (hasComma) {
        // remove precision for computation
        psplit = fnum.split('.');

        var cnum = psplit[0],
            parr = [],
            j = cnum.length,
            m = Math.floor(j / 3),
            n = cnum.length % 3 || 3; // n cannot be ZERO or causes infinite loop

        // break the number into chunks of 3 digits; first chunk may be less than 3
        for (var i = 0; i < j; i += n) {
            if (i != 0) {n = 3;}
            parr[parr.length] = cnum.substr(i, n);
            m -= 1;
        }

        // put chunks back together, separated by comma
        fnum = parr.join(',');

        // add the precision back in
        if (psplit[1]) {fnum += '.' + psplit[1];}
    }

    // replace the number portion of the format with fnum
    return format.replace(/[\d,?\.?]+/, fnum);
};

person Choy    schedule 19.05.2010    source источник


Ответы (1)


Это не полный код — отсутствуют методы isType и stripNonNumeric. Но в любом случае, поскольку это расширение самих объектов Number, вы можете использовать его как:

(42).format('0.00');

or

var a = 42;
a.format('0.00');

'12345'.format('0.00') не будет работать, так как '12345' здесь строка, но метод определен только для числа.

См. этот вопрос о том, почему вам нужно заключить числа в круглых скобках, и способы, которыми вы можете обойти это, не используя их, хотя я бы не рекомендовал это - причина всех этих слухов о программистах обслуживания, осях и прочем. Я не говорю, что каждый программист по сопровождению носит его в рюкзаке, но зачем рисковать. Они тоже любят хакерство, но не с кодом.. хахахаха

person Anurag    schedule 19.05.2010
comment
На самом деле вам не нужно заключать число в круглые скобки — вам просто нужно оставить пробел между числом и точкой. Таким образом, интерпретатор воспринимает точку не как разделитель дробей, а как оператор точки. 42 .format('0.00') - person Andris; 19.05.2010
comment
Да, но мне это не нравится :) См. прикрепленный вопрос - stackoverflow.com/questions/2726590/ для получения более подробной информации об этом. - person Anurag; 19.05.2010
comment
Я заметил, что он был неполным после повторного просмотра. Я не понимаю, как так много людей в сети утверждали, что это сработало для них ... но в любом случае вы довольно четко ответили на мой главный вопрос. Спасибо! Жаль, что я не могу заставить функцию работать. - person Choy; 20.05.2010
comment
погуглил stripNonNumeric и кое-что нашел. isType - это пустая трата времени - просто проверьте с помощью typeof format == string. См. рабочий пример здесь — jsfiddle.net/CEGXX. Обновление вашего вопроса с полным кодом. - person Anurag; 20.05.2010
comment
Потрясающий! Я собирался просто ответить, что нашел аналогичный код в Google, но у меня возникли проблемы с выводом десятичных знаков, но ваш второй код работает как шарм! Спасибо! - person Choy; 20.05.2010
comment
Этот код не работает, если у вас есть отрицательное значение с числом, кратным 3 цифрам. Например, (-345).format("0,000") производит -,100 - person rgvcorley; 05.12.2013