Moderator note: Please resist the urge to edit the code or remove this notice. The pattern of whitespace may be part of the question and therefore should not be tampered with unnecessarily. If you are in the "whitespace is insignificant" camp, you should be able to accept the code as is.
Is it ever possible that (a== 1 && a ==2 && a==3)
could evaluate to true
in JavaScript?
This is an interview question asked by a major tech company. It happened two weeks back, but I'm still trying to find the answer. I know we never write such code in our day-to-day job, but I'm curious.
Example without getters or valueOf:
This works because
==
invokestoString
which calls.join
for Arrays.Another solution, using
Symbol.toPrimitive
which is an ES6 equivalent oftoString/valueOf
:Okay, another hack with generators:
Yes, it is possible!
Honestly though, whether there is a way for it to evaluate to true or not (and as others have shown, there are multiple ways), the answer I'd be looking for, speaking as someone who has conducted hundreds of interviews, would be something along the lines of:
"Well, maybe yes under some weird set of circumstances that aren't immediately obvious to me... but if I encountered this in real code then I would use common debugging techniques to figure out how and why it was doing what it was doing and then immediately refactor the code to avoid that situation... but more importantly: I would absolutely NEVER write that code in the first place because that is the very definition of convoluted code, and I strive to never write convoluted code".
I guess some interviewers would take offense to having what is obviously meant to be a very tricky question called out, but I don't mind developers who have an opinion, especially when they can back it up with reasoned thought and can dovetail my question into a meaningful statement about themselves.
This is an inverted version of @Jeff's answer* where a hidden character (U+115F, U+1160 or U+3164) is used to create variables that look like
1
,2
and3
.* That answer can be simplified by using zero width non-joiner (U+200C) and zero width joiner (U+200D). Both of these characters are allowed inside identifiers but not at the beginning:
Other tricks are possible using the same idea e.g. by using Unicode variation selectors to create variables that look exactly alike (
a︀ = 1; a︁ = 2; a︀ == 1 && a︁ == 2; // true
).It can be accomplished using the following in the global scope. For
nodejs
useglobal
instead ofwindow
in the code below.This answer abuses the implicit variables provided by the global scope in the execution context by defining a getter to retrieve the variable.