How does the following piece of expression evaluates to "10" [duplicate]
Asked Answered
F

3

7

I have recently seen an expression from a source, which looks something like below -

++[[]][+[]]+[+[]]

Entering this into the Chrome (Windows 7, Version 27.0.1453.94 m) console shows a result of "10".

Can someone explain what's happening here?

JSFiddle.

Fleawort answered 31/5, 2013 at 6:27 Comment(0)
M
4

JavaScript is fairly flexible about converting between data types. The first thing to notice is that +[] evaluates to 0.* That lets us rewrite the expression as:

++[[]][0] + [0]

The next thing to notice is that ++[[]][0] is the preincrement operator applied to the first element of [[]]. Normally you can't apply ++ to an array, but JavaScript kindly converts the first element to 0, so the result is that ++[[]][0] evaluates to 1 (the first element of [[]] having now been incremented). It is kind of like this:

var a = [[]];
var b = ++a[0];
// now a will be [1] and b will be 1

That leaves us with:

1 + [0]

JavaScript now converts the int and the array to strings (since [0] is not a numeric value) and concatenates them together. Done!

* My understanding of how +[] becomes 0 is that it is a two-step process: first, [] is converted to a string primitive, which is the empty string. The empty string then converts to a number, which is zero. Via the same route, [1] evaluates to '1' and then to 1, [2] evaluates to 2, etc. However, [1, 2] evaluates to '1,2' which evaluates to NaN. (The last because the decimal point separator is ., not ,. I don't know what would happen if my locale were different.)

Maihem answered 31/5, 2013 at 6:52 Comment(4)
I pretty much assumed this far. Just wondering about converting [[]][0] to 0 part. Which conversion rule is followed during this process?Fleawort
@SayemAhmed - While the ++ cannot be applied to an array, it can be applied to an array element. The first element of [[]] is []; trying to apply ++ to that triggers JS to convert [] to 0 (just like it did with +[]).Maihem
Okay, I see your point. I am just finding the behavior of the ++ operator a little difficult to understand. You cannot apply it to array, that I get. But when you apply it to an array element and if the element is itself an array, then it gets converted to a primitive? Does the ECMA specification list this behavior somewhere?Fleawort
@SayemAhmed - §11.4.4 says that ++Expr starts (after some error checking) by evaluating ToNumber(GetValue(Expr)). §9.3 specifies that ToNumber for an object argument starts by evaluating ToPrimitive(value, Number). That, in turn, (per §9.1) calls the object's [[DefaultValue]] internal method. §8.12.8 describes how [[DefaultValue]] works for an object when the hint type is Number. The process specified there is essentially what I described: convert to a string (after first unsuccessfully trying to covert to a primitive using valueOf()) That's then parsed as a number (per §9.3).Maihem
K
2

This expression stringifies valid Javascript constructs that yelds NaN, numbers, boolean undefined etc.

e.g.

+[] -> 0  //The unary plus operator is applied to the result of toString applied to an empty array (which is an empty string)

!+[] -> true

You can have a look also at this question, and at the no alnum cheat sheets.

Kingly answered 31/5, 2013 at 6:44 Comment(2)
I figured out that part. I reduced the expression down to ++[[]][0]+[0], just can't figure out how the 1 is coming up here......Fleawort
Okay, I see the cheat sheet has listed ++[[]][+[]] as equivalent to 1, but doesn't give any explanation........Fleawort
B
2

+[] is a number conversion from array to number which is 0.

and +[0] is also 0.

So the final result can be deduced to (++0) + [0] which is 1+[0].

And for a number adding an array. They are converted to string so the result is actually '10'.

You can log typeof(++[[]][+[]]+[+[]]) to verify.

Bunchy answered 31/5, 2013 at 6:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.