(a==1 && a==2 && a==3)
return true
?”. The answer to the question, oddly enough, was positive.
const a = { num: 0, valueOf: function() { return this.num += 1 } }; const equality = (a==1 && a==2 && a==3); console.log(equality); // true
Ctrl + Shift + J
on Windows, or Cmd + Opt + J
on macOS. Copy this code, paste it into the console and make sure that the output really turns out true
.
valueOf()
.
(a==1 && a==2 && a==3)
, a non-strict equality operator is used. This means that during the calculation of the value of this expression, the casting will be used, that is, using ==
you can compare values of different types. I have already written a lot about this, so I will not go into details here. If you need to remember the features of the work of comparison operators in JS - refer to this material .
Object.prototype.valueOf()
. By default, this method returns the object for which it was called.
const a = { num: 0 }
valueOf()
for an object a
, it simply returns the object itself:
a.valueOf(); // {num: 0}
typeOf()
to check whether valueOf()
actually returns an object:
typeof a.valueOf(); // "object"
valueOf()
is that we can override this method in order to convert an object into a primitive value. In other words, you can use valueOf()
to return objects instead of strings, numbers, booleans, and so on. Take a look at the following code:
a.valueOf = function() { return this.num; }
valueOf()
method for object a
. Now, when calling valueOf()
, the value of a.num
.
a.valueOf(); // 0
valueOf()
returns 0! The most important thing here is that 0 is the value that is assigned to the property of the a.num
object. We can verify this by running several tests:
typeof a.valueOf(); // "number" a.num == a.valueOf() // true
(a==1 && a==2 && a==3)
, JavaScript will try to bring object a
to a numeric type before comparing it with a number. When performing a cast operation on a JavaScript object, it will first try to call the valueOf()
method.
valueOf()
method so that it now returns a.num
, which is a number, we can now do the following:
a == 0 // true
a.num
each time valueOf()
called. Fortunately, JavaScript has an assignment operator with addition, or an incremental assignment operator ( +=
).
let b = 1 console.log(b+=1); // 2 console.log(b+=1); // 3 console.log(b+=1); // 4
valueOf()
method:
a.valueOf = function() { return this.num += 1; }
this.num
, we will now, with each call to valueOf()
, return the value of this.num
, incremented by 1, and write the new value in this.num
.
const equality = (a==1 && a==2 && a==3); console.log(equality); // true
valueOf()
method, which returns a.num += 1
, in other words, returns a.num
value, incremented by one each time it is called. Now it remains only to compare two numbers. In our case, all comparisons will be true
.
a == 1 -> a.valueOf() == 1 -> a.num += 1 == 1 -> 0 += 1 == 1 -> 1 == 1 -> true a == 2 -> a.valueOf() == 2 -> a.num += 1 == 2 -> 1 += 1 == 2 -> 2 == 2 -> true a == 3 -> a.valueOf() == 3 -> a.num += 1 == 3 -> 2 += 1 == 3 -> 3 == 3 -> true
Source: https://habr.com/ru/post/347530/