Qu'est-ce qu'une expression côté gauche valide dans la grammaire JavaScript?
-
02-10-2019 - |
Question
D'accord, nous avons tous Le savoir ce que les expressions de gauche côté main valides sont. En quelque sorte. *
Mais, en regardant la définition de la norme ECMA-Script , Je suis très confus:
LeftHandSideExpression :
NewExpression
CallExpression
est-ce juste une erreur dans la définition, ou j'obtiens quelque chose de mal ici? Je veux dire, ne pas que cela signifie en fait que
new Object = 1; // NewExpression AssignmentOperator PrimaryExpression
function () { return foo; }() = 1;// CallExpression AssignmentOperator PrimaryExpression
sont censés être des expressions d'affectation valides?
* De mon humble compréhension, ce serait beaucoup plus logique:
LeftHandSideExpression :
Identifier
MemberExpression [ Expression ]
MemberExpression . IdentifierName
CallExpression [ Expression ]
CallExpression . IdentifierName
La solution
Pour répondre à votre question de façon concise, tout sous la production de LeftHandSideExpression
est un LeftHandSideExpression
valide.
Je pense que la question que vous posez vraiment est:
Qu'est-ce qu'un
LeftHandSideExpression
valide et aussi cessible?
La réponse à cette question est tout ce qui décide à un Reference
qui est un concept bien défini dans le cahier des charges. Dans votre exemple
new Object = 1;
Le new Object
est un LeftHandSideExpression
valide, mais elle ne résout pas à un Reference
.
(new Object).x = 1;
Le côté gauche est un MemberExpression . IdentifierName
qui, conformément à la spécification de l'étape finale est la suivante:
Retour d'une valeur de type référence ...
Si vous considérez 2 propriétés distinctes, il fait beaucoup plus de sens.
- Est-ce une LeftHandSideExpression valide?
- Est-ce une référence valide?
Propriété 1 est déterminée dans la phase d'analyse syntaxique et de la propriété 2 est déterminée dans la phase d'analyse sémantique. Consultez 8.7.2 PutValue (V, W) pour plus de détails.
Voici une explication complète dans la spécification elle-même:
8.7 La référence Spécification Type
Le type de référence est utilisé pour expliquer le comportement de ces opérateurs de suppression, typeof, et les opérateurs d'affectation. Par exemple, l'opérande gauche d'une cession devrait produire une référence. Le comportement de la cession pourrait, au contraire, être entièrement expliquée en termes d'analyse de cas sur la forme syntaxique de l'opérande gauche d'un opérateur d'affectation, mais une difficulté: les appels de fonction sont autorisés à retourner des références. Cette possibilité est admise uniquement pour des raisons d'objets d'accueil. Aucune fonction intégrée ECMAScript définie par cette spécification renvoie une référence et il n'y a aucune disposition pour une fonction définie par l'utilisateur pour renvoyer une référence. (Une autre raison de ne pas utiliser une analyse syntaxique de cas est qu'il serait long et difficile, affectant de nombreuses parties de la spécification.)
Après avoir pris un coup d'oeil à votre suggestion que je crois qu'il jetterait de certaines expressions valides (Note:. Je ne cautionne pas)
function OuterObj() {
this.Name = "Outer";
this.InnerObj = function() {
this.Name = "Inner";
}
}
var obj; (obj = new new OuterObj().InnerObj).Name = "Assigned";
Ceci est un cas où NewExpression
est important
Autres conseils
Ceci est une grammaire JavaScript alternative ne correspondra LeftHandSideExpressions valides, qui est, LeftHandSideExpressions qui sont en fait cessible.
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 ]
Chaque arguments pour lesquels le choix d'expression nouvelle ou appel associé est ambigu doivent être associés à la nouvelle expression le plus proche possible qui autrement ne correspondant Arguments. Je pense que c'est l'une des raisons pour lesquelles il est à la fois un NewExpression et un MemberExpression non terminal dans la grammaire JavaScript.