Какое действительное левое выражение в грамматике JavaScript?

Хорошо, мы все знаем, каковы действительные левые выражения. Вид. *

Но, глядя на определение из стандарта ECMA- Script, я очень смущен:

LeftHandSideExpression :
    NewExpression
    CallExpression

Это просто ошибка в определении, или я что-то не так понял? Я имею в виду, что это не означает, что

new Object = 1; // NewExpression AssignmentOperator PrimaryExpression
function () { return foo; }() = 1;// CallExpression AssignmentOperator PrimaryExpression

должны быть действительными выражениями присваивания?


* Из моего скромного понимания это будет иметь гораздо больше смысла:

LeftHandSideExpression :
    Identifier
    MemberExpression [ Expression ]
    MemberExpression . IdentifierName
    CallExpression [ Expression ]
    CallExpression . IdentifierName

суб >

Ответ 1

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


Я думаю, что вопрос, который вы действительно задаете, таков:

Что такое действительный LeftHandSideExpression, а также назначаемый?

Ответ на этот вопрос - это что-то, что разрешает Reference, который является четко определенным понятием в спецификации. В вашем примере

new Object = 1;

new Object является допустимым LeftHandSideExpression, но он не разрешает Reference.

(new Object).x = 1;

Левая часть - это MemberExpression . IdentifierName, которая согласно спецификации заключительный шаг:

Возвращает значение типа Reference ...


Если вы считаете это 2 отдельными свойствами, это имеет гораздо больший смысл.

  • Это допустимое выражение LeftHandSideExpression?
  • Это действительная ссылка?

Свойство 1 определяется в фазе синтаксического анализа, а свойство 2 определяется в фазе семантического анализа. Подробнее см. 8.7.2 PutValue (V, W).

Вот полное объяснение в самой спецификации:

8.7 Тип ссылочной спецификации

Тип Reference используется для объяснения поведения таких операторов как delete, typeof и операторов присваивания. Например, ожидается, что левый операнд задания будет давать ссылку. Поведение присваивания можно было бы объяснить только в терминах анализа случая синтаксической формы левого операнда оператора присваивания, но для одной трудности: вызовам функций разрешено возвращать ссылки. Эта возможность допускается исключительно ради объектов-хозяев. Никакая встроенная функция ECMAScript, определенная этой спецификацией, не возвращает ссылку, и не предусмотрено, что функция, определяемая пользователем, возвращает ссылку. (Другая причина не использовать синтаксический анализ случая - это то, что он был бы длинным и неудобным, затрагивая многие части спецификации.)


Посмотрев на ваше предложение, я считаю, что он сбросит некоторые допустимые выражения (Примечание: я не согласен с этим.)

function OuterObj() {
    this.Name = "Outer";
    this.InnerObj = function() {
        this.Name = "Inner";
    }
}

var obj; (obj = new new OuterObj().InnerObj).Name = "Assigned";

Это случай, когда NewExpression важен

Ответ 2

Это альтернативная грамматика JavaScript, которая будет соответствовать только действительным LeftHandSideExpressions, то есть LeftHandSideExpressions, которые фактически назначаются.

NewExpression :
    PrimaryExpression
    new NewExpressionQualifier Arguments
    new NewExpressionQualifier

NewExpressionQualifier :
    NewExpressionQualifier Qualifier
    NewExpression

CallExpression :
    NewExpression
    CallExpressionQualifier Arguments

CallExpressionQualifier :
    CallExpression
    CallExpressionQualifier Qualifier

LeftHandSideExpression :
    LeftHandSideExpression Qualifier
    CallExpression Qualifier
    Identifier
    ( LeftHandSideExpression )
    ( Expression , LeftHandSideExpression )

Qualifier :
    . IdentifierName
    [ Expression ]

Каждый аргумент, для которого выбор связанного нового или выражение вызова неоднозначен, должен быть связан с ближайшим возможным новым выражением, которое иначе не имело бы соответствующих аргументов. Я думаю, что это одна из причин, по которой в грамматике JavaScript есть как выражение NewExpression, так и выражение MemberExpression.