The result of isNaN(Number({})) is true
Although this statement is accurate, it's important to note that an object and a Boolean object are not interchangeable.
To clarify, the Number function in JavaScript converts its argument into a numeric value following specific rules outlined in the ECMAScript standard. When dealing with objects, the conversion process is more complex than simply converting all objects to NaN (Not-a-Number). Consider the following examples:
const obj0 = {}
const obj1 = {
toString() {
return 1;
}
}
const obj2 = {
toString() {
return 1;
},
valueOf() {
return 2;
}
}
const obj3 = {
toString() {
return 1;
},
valueOf() {
return 2;
},
[Symbol.toPrimitive]() {
return 3;
}
}
const obj4 = Object.create(null);
console.log(Number(obj0)); //NaN
console.log(Number(obj1)); //1
console.log(Number(obj2)); //2
console.log(Number(obj3)); //3
console.log(Number(obj4)); //Error
As demonstrated, not all objects are equivalent when converted to a number. Some objects have distinct conversion behaviors.
When Number receives an object as an argument, it attempts to convert it to a primitive type, prioritizing numbers. The conversion process involves multiple steps:
- Determine the hint as "number".
- Check if the object has a @@toPrimitive method.
- If available, call this method with the hint ("number").
- If no @@toPrimitive method exists, check for a valueOf method.
- This step occurs because the hint is "number", making valueOf the first choice.
- If valueOf isn't found, search for a toString method.
- Depending on the hint ("number" or "string"), either valueOf or toString will be used.
- If neither method is present, an error is raised.
After finding an appropriate method, execute it to obtain a numeric value.
At this point, we haven't discussed Boolean objects. This explanation pertains only to generic Number conversion. In summary, an object can be converted to a primitive number if it implements the necessary functionality.
Boolean objects do implement the required functionality through the valueOf method, which returns their boolean value:
const T1 = new Boolean(true);
const T2 = new Boolean(true);
console.log("T1.valueOf()", T1.valueOf());
console.log("typeof T1.valueOf()", typeof T1.valueOf());
console.log("T1 === T2", T1 === T2);
console.log("T1.valueOf() === T2.valueOf()", T1.valueOf() === T2.valueOf());
Hence, the equation
Number(new Boolean(true))
equals
Number(new Boolean(true).valueOf())
, which simplifies to
Number(true)
In general terms: Number(new Boolean(bool))
equals Number(bool)
Referencing the ToNumber conversion specification, true evaluates to 1, while false equates to 0. Therefore, Number(new Boolean(false)) === 0
since Number(false)
is indeed 0
. Similarly, Number(new Boolean(true)) === 1
.