Почему первая строка работает, а вторая строка выбрасывает run-time exception
?
Первая строка:
[[]][0]++; //this line works fine
Вторая строка:
[]++; //this lines throws exception
Почему первая строка работает, а вторая строка выбрасывает run-time exception
?
Первая строка:
[[]][0]++; //this line works fine
Вторая строка:
[]++; //this lines throws exception
[[]][0]++
эквивалентно
var tmp = [[]];
tmp[0] = tmp[0]+1;
tmp[0]
- пустой массив, который добавляется к числу 0
, который увеличивается до 1
.
Это работает только потому, что <array>[<index>]++
выглядит действительным. Требуется манипуляция типа, но он попадает туда.
Но []++
недействителен. Нет никакого способа сделать это имеющим смысл.
[] = []+1;
Левая часть здесь действительно недействительна. Вы не можете назначить пустой массив.
Оператор ++
(или действительно любой постфиксный оператор) требует, чтобы операнд был "ссылкой", то есть значением, которому можно назначить. []
является литералом, поэтому вы не можете его назначить. [[]][0]
- действительная ссылка на элемент временного массива.
0++; // not valid, `0` is a literal.
var a = [];
a++; // ok, `a` is assignable
Это редкий случай, когда Javascript делает что-то, что действительно имеет смысл. Рассмотрим
x[3]++; // Valid
3++; // Not valid
Если это имеет смысл для вас, то что удивительно в
[[]][0]++; // valid
[]++; // not valid
<array>[index]
- это "место", которое вы можете назначить или увеличить. Все это. Тот факт, что вы можете увеличивать a[<expr>]
, не означает, что вы можете увеличивать <expr>
.
Абсурдная часть состоит в том, что вы можете использовать []
как индекс, который имеет смысл преобразовать массив в пустую строку ""
, а затем в число 0
, но это известная проблема абсурдные неявные преобразования Javascript. Эти неявные правила преобразования - это большая бородавка Javascript и, например, подразумевают, что 1 == [1]
или оба []==false
и (![])==false
.
Javascript - чистая бессмыслица во многих местах... но на самом деле не здесь.