DEV Community

Cover image for Why (! + [] + [] + ![]).length is 9

Why (! + [] + [] + ![]).length is 9

Tomas Forsman on July 14, 2019

Edit: At the bottom I've added what I've figured out since I wrote this. Today I sat down and figured out why you get this result in JavaScript ...
Collapse
 
tpenguinltg profile image
tPenguinLTG •

JavaScript does operations from right to left.

In some cases it does, but not in this case. The reason you see behaviour that may appear to be right-to-left evaluation is because of operator precedence, where the unary ! has a higher precedence than the binary +.

+ actually evaluates from left to right, so more verbosely parenthesized, it looks like this:

(((!(+[])) + []) + (![])).length

Evaluating this parenthesized form step-by-step, we get this:

/*  1. */ (((!(+[])) + []) + (![])).length  // parethesized form.
/*  2. */ (((!0) + []) + (![])).length      // `+[]` is evaluated to `0`.
/*  3. */ (((!false) + []) + (![])).length  // `0` is coerced to the boolean `false`.
/*  4. */ ((true + []) + (![])).length      // `!false` is evaluated to `true`.
/*  5. */ (("true" + "") + (![])).length    // `[]` is coerced as a primitive to the string `""`, which means `true` is also coerced to a string.
/*  6. */ ("true" + (![])).length           // `"true" + ""` is string concatenation, which evaluates to `"true"`.
/*  7. */ ("true" + (!true)).length         // `[]` is coerced to the boolean `true`.
/*  8. */ ("true" + false).length           // `!true` evaluates to `false`.
/*  9. */ ("true" + "false").length         // `false` is coerced to a string because `"true"` is a string.
/* 10. */ "truefalse".length                // `"true" + "false"` is evaluated as string concatenation to `"truefalse".
/* 11. */ 9                                 // the length of `"truefalse"` is `9`.
Collapse
 
tomasforsman profile image
Tomas Forsman •

The first + is unary, right?

Collapse
 
tpenguinltg profile image
tPenguinLTG •

Indeed it is.

Collapse
 
karataev profile image
Eugene Karataev •

If I'm not sure what's going on with the JS code, I use ASTexplorer to look at the code with the compiler's eyes. It converts a code string into the tree of instructions to be executed by the compiler step by step.
But sometimes text representation of a tree is not expressive enough, so I built a little tool which visualizes an AST tree.
For (! + [] + [] + ![]).length AST in graph form looks like this:
ast
In runtime calculations starts from the bottom left and flow to the top.

Collapse
 
tomasforsman profile image
Tomas Forsman •

love this!

Collapse
 
jacobmparis profile image
Jacob Paris • • Edited
(({})[[]]+[]).length

This is also equal to 9 but for a very different reason

Collapse
 
tyskie profile image
tyskie •
(-1/0+[]).length

This one too but for yet another reason

Collapse
 
moopet profile image
Ben Sinclair •
(({})[[]]+[])[1]+(({})[[]]+[])[5]+(({})[[]]+[])[1]+(({})[[]]+[])[3]

Standing on the shoulders of giants.

Thread Thread
 
jacobmparis profile image
Jacob Paris •

You can stand on your own shoulders this was perfect

Collapse
 
kassem profile image
Kassem •

Interesting breakdown. I might have missed something but I think "truefalls" should be "truefalse".

Collapse
 
tomasforsman profile image
Tomas Forsman •

Indeed it should =D That's dyslexia for ya.

Collapse
 
tadman profile image
Scott Tadman •

Ain't that the truef.

Collapse
 
sagarb3 profile image
Sagar Bhattacharya • • Edited

It is a great observation , typecasting in JS is weird. This is the reason I love this platform.

Collapse
 
alexluong profile image
Alex Luong •

AWESOME INTERVIEW QUESTION!!!

Collapse
 
aerosboss profile image
aerosboss •

jajaja many brains will explode

Collapse
 
nabbisen profile image
nabbisen •

Totally greatly interesting.
Thank you for your great post.
The behaviors seem a bit strange and are beautiful 😆

Collapse
 
vocab_king profile image
WhistlerIAM •

Hi.
This is very well documented in the Boolean coercion abstract operation by ECMAScript language.
So, there are two operations that you may check out.

  1. ToBoolean and ToString.
Collapse
 
acido_binario profile image
🍝 sadder sCrypt Kiddie 𖤐🕷️ •

Is this ease of programming?

Collapse
 
copy_pasta_chef profile image
Essien •

Does this have anything to do with the esoteric version of JS? en.m.wikipedia.org/wiki/JSFuck