javascript – Can (a== 1 && a ==2 && a==3) ever evaluate to true? – Stack Overflow
Yes, it can. IMHO it is one of the several undesirable consequences of loosely typed languages. In fact, according to an almost anonymous user:
If you take advantage of how
==
works, you could simply create an object with a customtoString
(orvalueOf
) function that changes what it returns each time it is used such that it satisfies all three conditions.const a = { i: 1, toString: function () { return a.i++; } } if(a == 1 && a == 2 && a == 3) { console.log('Hello World!'); }
The reason this works is due to the use of the loose equality operator. When using loose equality, if one of the operands is of a different type than the other, the engine will attempt to convert one to the other. In the case of an object on the left and a number on the right, it will attempt to convert the object to a number by first calling
valueOf
if it is callable, and failing that, it will calltoString
. I usedtoString
in this case simply because it’s what came to mind,valueOf
would make more sense. If I instead returned a string fromtoString
, the engine would have then attempted to convert the string to a number giving us the same end result, though with a slightly longer path.
Worst, it is also possible using the === operator!
var i = 0; with({ get a() { return ++i; } }) { if (a == 1 && a == 2 && a == 3) console.log("wohoo"); }
This uses a getter inside of a
with
statement to leta
evaluate to three different values.… this still does not mean this should be used in real code…
Even worse, this trick will also work with the use of
===
.var i = 0; with({ get a() { return ++i; } }) { if (a !== a) console.log("yep, this is printed."); }