Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Add attribute to instance of "Number"

I want to see if a number is a multiple of π. So ideally it would behave exactly like an ordinary number, but with extra functionality:

>>> pi
3.14...
>>> pi.isMultipleOfPi
true
>>> b = pi * 5
>>> b.isMultipleOfPi
true

With wishful thinking

>>> c = pi + 1
>>> c.isMultipleOfPi
false
>>> d = pi + 2 * pi
>>> d.isMultipleOfPi
true

Is there a way to achieve something like that in Javascript? I think this would be pretty straight forward in Python, but there seems to be no way to create overloads for addition/multiplication etc. in JS. If there were, I could simply extent the Number class.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Setting something on Number.prototype = function also doesn’t seem to work as it sets it for the entire class and not on an instance.

>Solution :

I thought at first you wanted to do this for all numbers, which is answered here.

But if you only want to do this for one specific number, you can, but you probably won’t want to. 99.9999999999998% of all numbers you work with in JavaScript are primitives, not objects, and so they don’t have any properties (the ones they seem to have only come from Number.prototype [or, in turn, from Object.primitive], which the JavaScript engine will use if you try to access a property on a number primitive).

You could make a number object instead, and put the property on that:

const c = new Number(Math.PI);
c.isMultipleOfPI = true;
console.log(c);
console.log(String(c));
console.log(c.isMultipleOfPI);

The problem with that, though, is demonstrated by the console.log(c); line above. With Chrome’s devtools (and perhaps others), you see this:

{
    isMultipleOfPI: true,
}

rather than 3.141592653589793 as you might be expecting.

The reason is that c is an object, not a primitive, and some things that use it (such as console.log) may treat it primarily as an object rather than primarily as a number.

Math and string concatenation work, though:

const c = new Number(Math.PI);
c.isMultipleOfPI = true;
console.log(c * 2);
console.log(c - 2);
console.log(c + 2);
console.log(c / 2);
console.log("The number is " + c);

Just beware that Number instances (objects) are objects, and that very, very little code is written explicitly to work with them properly. Most code using numbers expects number primitives.

Alternatively, you could make an accessor property on Number.prototype (Pointy shows you how) that determines if the number it’s called on is a multiple of PI and returns the right flag. That would give you the syntax you showed, but on all numbers. But it is a function call, so accessing the property works it out each time. Just having a isMultipleOfPI(num) function might be clearer.

In a comment you’ve written:

Because Number.prototype = function(){ return self % Math.PI ~ 0 } is not what I’m looking for. I would wish to distinguish between 3.14 vs 3.14 with isMultipleOfPi property.

The only way to do that is to use Number objects rather than number primitives, as described above.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading