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