Почему || a = 'bar' получит ошибку ссылки в javascript? - PullRequest
0 голосов
/ 18 февраля 2020

Фрагмент кода:

var a = 'foo'
a || a = 'bar'

Я ожидал, что он может работать нормально, что означает, что a будет 'bar' наконец. Но я получил ошибку

Uncaught SyntaxError: Недопустимая левая часть в присваивании.

В связи с ошибкой я подумал, что, возможно, что-то не так с левым выражением a || a. Кажется, что a || a здесь недопустимо. Но почему? Я обращаюсь к спецификации языка экмаскриптов за помощью. В 12.15.1 Stati c Семантика: ранние ошибки , я нахожу:

Это ранняя ссылочная ошибка, если LeftHandSideExpression не является ни ObjectLiteral, ни ArrayLiteral, ни AssignmentTargetType для LeftHandSideExpression недопустимы.

Таким образом, AssignmentTargetType для LeftHandSideExpression a||a недопустим. почему a||a AssignmentTargetType недопустим. Об этом в спецификации просто сказано:

12.15.3 Stati c Семантика: AssignmentTargetType

Ass ignmentExpression:

YieldExpression

ArrowFunction

AsyncArrowFunction

LeftHandSideExpression = AssignmentExpression

LeftHandSide Expression Assignment

Возврат недействителен.

Я не могу понять, почему AssignmentTargetType * 1048 недопустим в зависимости от того, что ему дано.

Мой вопрос: почему a||a = 'bar' получит ошибку ссылки в javascript? Если это что-то с недопустимым AssignmentTargetType для LeftHandSideExpression, почему a||a недопустимо?

Ответы [ 3 ]

2 голосов
/ 18 февраля 2020

Мой вопрос: почему a||a = 'bar' получит ошибку ссылки в javascript?

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

Если это что-то с недопустимым AssignmentTargetType для LeftHandSideExpression, почему a||a недопустимо?

Это намного проще, чем это: синтаксис выражения присваивания, среди прочего,

LeftHandSideExpression = AssignmentExpression

Это означает, что в левой части = нам нужен LeftHandSideExpression.

|| это LogicalORExpression, но не LeftHandSideExpression, и поэтому он не может появляться в этой позиции.

Вы можете думать о различных типах выражения, организованные в иерархию (я упростил следующий пример, пропустив некоторые типы выражений):

AssignmentExpression
         ^
         |
LogicalORExpression
         ^
         |
LeftHandSideExpression
         ^
         |
PrimaryExpression
         ^
         |
Identifier Reference

То есть: ссылка на идентификатор - это PrimaryExpression, это LeftHandSideExpression, et c.

LogicalORExpression выше в иерархии, что делает его надмножеством, включающим LeftHandSideExpression. Это означает, что есть некоторые выражения, такие как ||, которые являются LogicalORExpression, но не LeftHandSideExpression.

1 голос
/ 18 февраля 2020

JavaScript будет выполняться слева направо. a || a оценивается как foo, прежде чем вы попытаетесь переназначить новое значение для a. Это означает, что вы пытаетесь запустить 'foo' = 'bar', что приводит вас к ошибке неверного назначения левой руки.

0 голосов
/ 18 февраля 2020

Обновление: как указал @Teemu. Обновлены комментарии.

var a = 'foo'
a || a = 'bar' // a || a evaluates to 'foo', So it will be `'foo' = 'bar'` here

a || (a = 'bar') // will result to a is 'foo'

a = ''
a || (a = 'bar') // will result to a is 'bar'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...