loading...
Cover image for Can (aᅠ == 1 && a == 2 && ᅠa == 3) equal true?

Can (aᅠ == 1 && a == 2 && ᅠa == 3) equal true?

superkarolis profile image Karolis Ramanauskas Originally published at karolisram.com on ・1 min read

Here is a JavaScript trivia question. Can the expression (aᅠ == 1 && a == 2 && ᅠa == 3) ever evaluate to true? Well, today I found out it can. Run the below code and see for yourself.

Now let's look at seemingly the same code below. Try to run it. This time the expression does not evaluate to true. So what changed?

The difference is actally really simple and much less mysterious once you figure out what's happening. Apparently, there is a Unicode character called Halfwidth Hangul Filler which is a Korean symbol and is, for all intents and purposes, invisible. So the reason why the first code snippet evaluates to true is because the three variables a are in fact three distinct variables. One of them is prepended with halfwidth hangul filler, another one is left intact and the third one is appended with the hidden character.

Now next time someone asks you whether (aᅠ == 1 && a == 2 && ᅠa == 3) can ever equal to true, you can answer them that yes, indeed it can (with a small caveat) 😀

Discussion

pic
Editor guide
Collapse
pichardoj profile image
J. Pichardo

Nice post, I wouldn't have thought about using an "invisible" character.

Now, for the curious people, there is also another way :)



const a = {
  valueOf: (function(){
      let x = 1;
      return () => x++;
    })()
}

console.log(a == 1 && a == 2 && a == 3); // => true

Just for reference, the concepts used here are type coercion, closures and immediate function invocation.

Regards

p.s. can a === 1 && a === 2 && a === 3 evaluate to true?

Collapse
ailrun profile image
Junyoung Clare Jang

Yes, you also can make true from a === 1 && a === 2 && a === 3 without invisible character, since, we have getter.

let i = 0;
Object.defineProperty(window, 'a', {
  get: function() {
    return ++i;
  }
});
console.log(a === 1 && a === 2 && a === 3);
Collapse
pichardoj profile image
J. Pichardo

Precisely, nice catch.

Collapse
superkarolis profile image
Karolis Ramanauskas Author

Nice, interesting approach!

Collapse
nreek profile image
Henrique Marques

Nice! Way more useful and interesting than the actual post.

Collapse
nestedsoftware profile image
Nested Software

This is very cool and scary!

Collapse
ekeyte profile image
Eric Keyte

This feels a little clickbait-y. It feels the same as photographing two glasses of water after 3 hours in the freezer, and then saying, “we put two glasses of water in the freezer and one of them didn’t freeze!” And then revealing that one glass was actually full of vodka.

I don’t want to try to misunderstand the spirit of this article, but I don’t get why any of this is relevant.

Collapse
eclejian profile image
eclejian

Haha exactly.

Collapse
theodesp profile image
Theofanis Despoudis

Changing var to let will give you a hint

Collapse
superkarolis profile image
Karolis Ramanauskas Author

That's right! Although for the hint to be useful you have to know that let throws an exception if you try to redeclare a variable.

Collapse
isaacleimgruber profile image
IsaacLeimgruber

Does it not work if you set a to True since then 1,2,3 are cast to booleans and are evaluated at True aswell?

Collapse
pichardoj profile image
J. Pichardo

1,2,3 are not casted to booleans as they are primitive types themselves.

Collapse
isaacleimgruber profile image
IsaacLeimgruber

In C bool is int is char

Collapse
hoz1982 profile image
Alessandro Romani

lol nice post :)

Collapse
zasuh_ profile image
Žane Suhadolnik

Maybe with the === operator?

Collapse
gmartigny profile image
Guillaume Martigny

As long as it's 3 different variables, the === operator will not be helpful. This is a "magic" trick, not a bug ;)