(4 || x = 5) ReferenceError вместо SyntaxError

Почему следующий код возвращает ReferenceError вместо SyntaxError?

4 || x = 5; // Uncaught ReferenceError: Invalid left-hand side in assignment

Вот как AssignmentExpression определяется в соответствии с ECMAScript 5.1:

AssignmentExpression :
    ConditionalExpression
    LeftHandSideExpression = AssignmentExpression
    LeftHandSideExpression AssignmentOperator AssignmentExpression

В этом случае 4 || x это не LeftHandSideExpression, а LogicalORExpression это не входит в LeftHandSideExpression, Как работает парсер?

3 ответа

Это синтаксически неверно, и по спецификации вы должны получить SyntaxError, но ваш браузер странно относится к типу исключения.

Вы должны получить раннюю ReferenceError для таких случаев, как

1 = 2;

где грамматика говорит, что левая сторона в порядке, но левая сторона не является ни литералом массива, ни литералом объекта, а IsValidSimpleAssignmentTarget не является истинным для левой стороны. Вы должны получить SyntaxError, когда грамматика отклоняет ваш код (и в некоторых других случаях тоже). Похоже, ваш браузер использует слишком разрешающую версию LeftHandSideExpression и отфильтровывает грамматически неверные левые части в той же проверке, что и IsValidSimpleAssignmentTarget, и выдает ту же ошибку.

Интересная находка! Я считаю, что сканер читает слева направо. Сначала это оценка 4 || x, Результат этого выражения всегда будет 4, поскольку 4 "правда". Таким образом, он затем оценивает 4 = 5, который выдает ошибку, так как вы не можете переопределить значение целого числа.

Дополнительную информацию о порядке приоритета можно найти здесь: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence

Мои знания JavaScript говорят мне, что "=" имеет меньший приоритет, чем логическое ИЛИ "||" вот почему вы получаете ReferenceError..

делая это:

4 || (x = 5)

вы вообще не получаете ошибку

отредактировано: внимательно читая ваш вопрос.. что вы действительно хотите знать, так это то, как работает синтаксический анализатор.. ну..JS - интерпретируемый язык и пытается быть быстрым, так

true || destroyWorld() // will never be called.. actually..the parser will never read it

когда я добавил скобки, я увеличил приоритет всего выражения.. оператор присваивания имеет один из самых низких

(проверьте ссылку в другом ответе)

Другие вопросы по тегам