As the documentation describes this behaviour for parseInt(), but not for the Number() constructor called as a function, I was looking for some insight on whether this is reliable and if there's a reference to this from an official source. Sample code:
let adder = (function () { let sum = 0 return function add(num) { sum += num add.toString = () => sum //method is overwritten to return value return add } })() console.log(Number(adder(5)(2)(3))) // => 10
See the specification . Calling Number
will call ToNumeric(value)
with the argument, which will call ToPrimitive with the argument, which will (usually) call OrdinaryToPrimitive with the argument and a hint of number
, which does:
So, in the case of converting an object to a numeric primitive, will first attempt to call a valueOf
method on the object, if it exists. If such a method doesn't exist, it'll attempt to call the toString
method on the object.
Yes, relying on toString
being invoked in case valueOf
doesn't exist is reliable.
Live snippet illustrating how valueOf
is called first, if it exists:
let adder = (function () { let sum = 0 return function add(num) { sum += num add.toString = () => { console.log('toString called'); return sum; //method is overwritten to return value }; add.valueOf = () => { console.log('valueOf called'); return sum; //method is overwritten to return value }; return add } })() console.log(Number(adder(5)(2)(3))) // => 10
If the object doesn't have an own property of toString
or valueOf
, Object.prototype.toString
will be called, resulting in [object Object]
- but that won't be coercable to a number, resulting in NaN
.
let adder = (function () { let sum = 0 return function add(num) { sum += num return add } })() console.log(Number(adder(5)(2)(3))) // => 10
And if the object doesn't inherit from Object.prototype
and doesn't have toString
or valueOf
anywhere in its prototype chain, an error will be thrown:
let adder = Object.create(null); console.log(Number(adder))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.