Что такое правильное левостороннее выражение в грамматике JavaScript? - PullRequest
15 голосов
/ 14 сентября 2010

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

Но, глядя на определение из стандарта 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

Ответы [ 2 ]

11 голосов
/ 14 сентября 2010

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


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

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

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

new Object = 1;

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

(new Object).x = 1;

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

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


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

  1. Это действительное выражение LeftHandSideExpression?
  2. Это действительная ссылка?

Свойство 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 голосов
/ 14 сентября 2017

Это альтернативная грамматика 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.

...