admin管理员组

文章数量:1183725

Why does the first line work while the second line throws run-time exception?

The first line:

[[]][0]++; //this line works fine

The second line:

[]++; //this lines throws exception

Why does the first line work while the second line throws run-time exception?

The first line:

[[]][0]++; //this line works fine

The second line:

[]++; //this lines throws exception
Share Improve this question edited Sep 23, 2017 at 16:11 Jean-François Corbett 38.5k30 gold badges142 silver badges189 bronze badges asked Aug 26, 2017 at 8:52 Ervin SzilagyiErvin Szilagyi 16.8k2 gold badges35 silver badges53 bronze badges 7
  • 1 Yeah, I think a lot of people read Dave's blog: davidwalsh.name/thinking-javascript – Mark Commented Aug 26, 2017 at 9:05
  • 7 Because Javascript. – Reinstate Monica Commented Aug 26, 2017 at 13:49
  • Why would you expect otherwise? Can you explain why the first line should throw an exception, or what the second line should do when it would not? – Bergi Commented Aug 26, 2017 at 15:44
  • @Bergi They both appear to do the same thing: Increment an empty array. They just do it differently. I would expect them both to throw, as incrementing an array is nonsense – Suppen Commented Aug 26, 2017 at 16:01
  • 1 That's how it actually works, as described by the accepted answer. They just appear to do the exact same thing in different ways – Suppen Commented Aug 26, 2017 at 16:09
 |  Show 2 more comments

3 Answers 3

Reset to default 18
[[]][0]++

is equivalent to

var tmp = [[]];
tmp[0] = tmp[0]+1;

tmp[0] is an empty array, which is cast to the number 0, which increments to 1.

This only works because <array>[<index>]++ looks valid. It takes some type juggling, but it gets there.

But []++ is outright invalid. There's no way to make it make sense.

[] = []+1;

The left-hand side here is indeed invalid. You can't assign to an empty array.

The ++ operator (or indeed any postfix operator) requires the operand to be a "reference" - that is, a value that can be assigned to. [] is a literal, so you can't assign to it. [[]][0] is a valid reference to an element of a temporary array.

0++; // not valid, `0` is a literal.
var a = [];
a++; // ok, `a` is assignable

This is a rare case in which Javascript does something that actually makes sense. Consider

x[3]++; // Valid
3++;    // Not valid

If this make sense for you, then what is surprising about

[[]][0]++; // valid
[]++;      // not valid

<array>[index] is "a place" that you can assign or increment. That's all. The fact that you can increment a[<expr>] doesn't imply that you can increment <expr>.

The absurd part is that you can use [] as an index, that has the meaning of converting the array to an empty string "" and then to the number 0, but this is the well known problem of absurd implicit conversions of Javascript. Those implicit conversion rules are a big wart of Javascript and for example imply that 1 == [1] or that both []==false and (![])==false.

Javascript is pure nonsense in a lot of places... but not really here.

本文标签: javascriptWhy does 0 work butthrows runtime exceptionStack Overflow