Extend the number class

I want to extend the number class to have instance functions such as odd and even so I can do something like this:

2.odd() => false
2.even() => true
1.even() => false
1.odd()  => true

Extending classes is a good Ruby practise: "Ruby check if even number, float".

Is the same true in JavaScript, or does it cause performance issues or some other problem?

Anyway, I can't extend despite my best efforts:

var NumberInstanceExtensions = {
    accuracy: function(){
        return 'This is cool ' + this
    }
}
$.extend(Number.prototype,NumberInstanceExtensions);

alert( $.type(5) );      //-> number
//alert( 5.accuracy() ); //-> Uncaught SyntaxError: Unexpected token ILLEGAL 

http://jsfiddle.net/VLPTb/2/

How can I get this to work? The syntax error makes me think this isn't how JavaScript works on a fundamental level. Is my best bet extending the Math class and doing this instead:

Math.odd(2)  => false
Math.even(2) => true
Math.even(1) => false
Math.odd(1)  => true

That seems far more inelegant than 2.odd().

Answers:

Answer

I think as long as you understand the side-effects of your "extension" then you're okay. I often modify the String prototype to add an "elipsis" method so I can do things like

"SomeString".elipsis()

But start at the beginning. You're not "extending classes" in JavaScript. JavaScript is a prototype-based language. You can modify prototypes to do what you need.

You won't be able to add a method directly to the number itself. You can, however modify the prototype of the Number object:

Number.prototype.even = function(){    
    return this.valueOf() % 2 === 0;
}

With this, you won't be able to use the following syntax:

10.even();

But, since you aren't hard-coding stuff, otherwise you wouldn't need this function anyways, you CAN do the following:

var a = 10;
a.even(); //true

I might say that you could consider adding a utilities object to do these things, because modifying primitive prototypes is not always guaranteed to be side-effect free.

This function does not really provide any gain for you. You're checking for odd and even, replacing one line of code with another. Think about the difference:

var a = 10;
var aIsEven = a.even();

vs:

var a = 10;
var aIsEven = a % 2 === 0;

You gain three characters of code, and the second option is less likely to break your "JavaScript".

Answer

You can extend natives JS objects by using (for example) Number.prototype.myFn = function(){}.

So you could do :

Math.prototype.odd = function(n){
    return n % 2 === 0;
};

Math.prototype.even = function(n){
    return n % 2 === 1;
};

And then use it like so :

var two = 2;
console.log(Math.odd(2)); // true

BUT I would strongly advise you against extending natives in JavaScript. You can read more about it here

EDIT : After trying my code on JSFiddle, it appears the Math object has no prototype, you can read more about it here. The code above won't work !

Instead, you could do :

Math.odd = function(n){
    return n % 2 === 0;
};

Math.even = function(n){
    return n % 2 === 1;
};

console.log(Math.odd(2)); // true

or :

Number.prototype.odd = function(){
    return this % 2 === 0;
};

Number.prototype.even = function(){
    return this % 2 === 1;
};

console.log(new Number(2).odd()); // true
Answer

I'd like to point out that that is already available in the numbers class.

Just use the boolean methods, odd? and even?

2.odd?
=> false

2.even?
=> true

Hope this helps.

No need to create a new class, it already exists in the numbers class.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.