DEV Community

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

Posted on • Originally published at karolisram.com on

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

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) 😀

Top comments (16)

Collapse
 
pichardoj profile image
J. Pichardo • Edited

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

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

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 • Edited

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 ;)