Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why should you not use Number as a constructor? [duplicate]

People also ask

What does Number() do JavaScript?

The Number() method converts a value to a number. If the value cannot be converted, NaN is returned.

What is Number constructor in JavaScript?

The Number constructor contains constants and methods for working with numbers. Values of other types can be converted to numbers using the Number() function. The JavaScript Number type is a double-precision 64-bit binary format IEEE 754 value, like double in Java or C#.

How to double a Number in JavaScript?

numbers = [1,2,3,4,5]; function doubling(number) { number *= 2; return number; } obj = {}; for (var i = 0; i < numbers. length; i++) doubled = doubling(numbers[i]); obj[numbers[i]] = doubled; console. log(obj);

Is Number in JavaScript?

Definition and Usage. The Number. isInteger() method returns true if a value is an integer of the datatype Number. Otherwise it returns false .


In addition to breaking === and typeof returning "object", using the Number constructor also changes the way the value is used in boolean contexts. Since "new Number(0)" is an object, not a literal value, it evaluates as "true" because it is not null. So for example:

var n1 = 0;
var n2 = new Number(0);

n1 == n2  // true
n1 === n2 // false
if (n1) {
    // Doesn't execute
}
if (n2) {
    // Does execute, because n2 is an object that is not null
}

Edit: Even worse than breaking === between number literals and Number objects, == doesn't even work between two Number objects (at least not in the intuitive way -- they test for identity, not equality).

var n1 = new Number(3);
var n2 = new Number(3);

alert(n1 == n2); // false
alert(n1 === n2); // false

var number = new Number(3);
alert(typeof number); // gives "object"

Making the variable number have a type of Object is probably not the most desired outcome. Whereas:

var number = Number(3);
alert(typeof number); // gives "number"

new Number() does not return the same object as a number literal. This means that using new Number() breaks ===, which is the best way to check for exact equality in Javascript.

>>> 3 == 1 + 2
true
>>> 3 === 1 + 2
true
>>> new Number(3) == 1 + 2
true
>>> new Number(3) === 1 + 2
false

You can find the rationale for JSLint's behavior in the author's book, JavaScript: The Good Parts, in Appendix C.


Unfortunately, the JSLint docs don't go into any further detail than "does not expect to see", so we're left to guess. My own suspicion is that this is to make type-checking easier:

assert(typeof 3             === "number");
assert(typeof new Number(3) === "object");

If you mix the two in your code, your type checks become more complex:

if (typeof foo === "number" || foo instanceof Number) { … }

However, JSLint also takes issue with the Object and Array constructors, which do not make this distinction, so it may simply be the author's coding-style preference:

assert(typeof []           === "object");
assert(typeof new Array()  === "object");
assert(typeof {}           === "object");
assert(typeof new Object() === "object");

Edit: Steven's answer raises an excellent point — the non-typecasting equality operator (===). Number objects and number primitives will never be considered equal by this operator, even if their values are the same:

assert(3 !== new Number(3));

It's slower, and requires more memory. The runtime can treat immutable literals as immutable literals. That means that when it encounters 3 somewhere in code, it can optimize that into a shared object. When you use the Number constructor, new memory is allocated for each instance.


in JavaScript, an Object type is not equal to another Object type, even when they have the exact same value, unless they are both the EXACT SAME object.

In other words, in Matthew's example below, n1 == n2 is false because you are comparing two REFERENCES to two SEPARATE objects, but n1 == n1 is true because you are comparing references to the EXACT SAME object.

So, while I now understand why using Number as a constructor can cause problems, I found you can use the valueOf property when comparing Number objects.

In other words, n1.valueOf == n2.valueOf is true! (This is because you're comparing the return values of the valueOf FUNCTION, not the REFERENCES to the objects themselves.)

This answer / summry was extracted from the question where it does not belong.