Question

i'm trying to extend the Number object with a function that has two sub-functions. It works fine, except that the sub-functions can't access the Number object value via this and I don't figured out how to access it or if this is possible.

My code looks something like this

var currency = function(prefix) {
    var val = this.toString();
    prefix = prefix || 'R$';

    if(val > 99999) {
        val = val.replace(/(\d+)(\d{3})(\d{2})$/,prefix + " $1.$2,$3");
    } else if(val == 0) {
        val = prefix + ' 0,00';
    } else {
       val = val.replace(/(\d+)(\d{2})$/, prefix + " $1,$2");
    }
    return val;
};

currency.cents = function() {
    var val = this.toString();
    return val == 0 ? '00' : val.substring(val.length - 2);
};

currency.integer = function() {
    var val = this.toString();
    return val == 0 ? '0' : val.substring(0, val.length - 2);
};

Number.prototype.currency = currency; 

alert((12345).currency()); // "R$ 123,45"
alert((12345).currency.cents()); // return " }"

The problem is in the line "var val = this.toString();" because this refers to the function itself, not the value of the Number object.

Is there any way to accomplish this?

Second question: Why I need to put ( ) around the number 12345 for this to work? I'm not extending the number object and 12345 is not an instance of it?

Thanks in advance

Was it helpful?

Solution

It may not look as nice as what you are trying to do, but you could add all three methods directly to the prototype like this.

var currency = function(prefix) {
    var val = this.toString();
    prefix = prefix || 'R$';

    if(val > 99999) {
        val = val.replace(/(\d+)(\d{3})(\d{2})$/,prefix + " $1.$2,$3");
    } else if(val == 0) {
        val = prefix + ' 0,00';
    } else {
       val = val.replace(/(\d+)(\d{2})$/, prefix + " $1,$2");
    }
    return val;
};

var currencyCents = function() {
    var val = this.currency();
    return val == 0 ? '00' : val.substring(val.length - 2);
};

var currencyInteger = function() {
    var val = this.currency();
    return val == 0 ? '0' : val.substring(0, val.length - 2);
};

Number.prototype.currency = currency;
Number.prototype.currencyCents = currencyCents;
Number.prototype.currencyInteger = currencyInteger;

alert((12345).currency());         // R$ 123,45
alert((12345).currencyCents());    // 45
alert((12345).currencyInteger());  // R$ 123,

And now for your second question..

Why I need to put ( ) around the number 12345 for this to work? I'm not extending the number object and 12345 is not an instance of it?

I found this question a lot trickier. I found the answer in Nick Craver's answer to Why don't number literals have access to Number methods? - it's because numbers can have decimals, so surround the number with parenthesis to make it clear that the period is for a function call and not for the decimal portion of the number.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top