Understand valueOf() in JavaScript
The valueOf()
function is a special function on all JavaScript objects. According to the Mozilla docs, the valueOf()
function "returns the primitive value of the specified object." There are 6 primitive types in JavaScript:
- Boolean:
true
andfalse
- Number:
-1
,0
,3.14
, etc. - String:
'foo'
' - Null
- Undefined
- Symbol:
Symbol('mySymbol')
The valueOf()
function should return a value whose typeof
is one of the above types. Here's what valueOf()
returns for 3 common JavaScript classes: String
, Number
, and Date
. String#valueOf()
and Number#valueOf()
"unbox" the object and give you the corresponding primitive string or number. Date#valueOf()
gives you the JavaScript timestamp.
const s = new String('test');
typeof s; // 'object'
s.valueOf(); // 'test'
typeof s.valueOf(); // 'string'
const n = new Number(42);
n.valueOf(); // 42
const d = new Date('2019-06-01');
d.valueOf(); // 1559347200000
JavaScript uses the valueOf()
function for type coercion when comparing values using the operators ==
(as opposed to ===
), <
, >
, <=
, and >=
. For example, here is the part of the JavaScript language specification that discusses using valueOf()
for the <
operator.
Suppose you have an object whose valueOf()
always returns 0. As far as the <
and ==
operators are concerned, this object is equivalent to the primitive number 0. However, for ==
, this object is not equivalent to new Number(0)
, because JavaScript does not call valueOf()
when using ==
to compare two objects.
class MyClass {
valueOf() {
return 0;
}
}
const obj = new MyClass();
// For the purposes of `<`, `>`, `>=` and `<=`, `obj` is
// equivalent to 0.
obj < new Number(-1); // false
obj > new Number(-1); // true
obj < -1; // false
obj > -1; // true
// For the purposes of `==`, `obj` is equivalent to 0 as a primitive,
// but not 0 as a Number object. This is because both `obj` and
// `new Number(0)` are objects, so JS does not call `valueOf()`.
obj == new Number(0); // false
obj == 0; // true
0 == obj; // true
// `===` skips calling `valueOf()`.
obj === Number(0); // false