在Node.js的REPL中(也已在SpiderMonkey中进行了测试)
var foo = null;
(foo) = "bar";
有效,foo
其后等于"bar"
相对于null
。
这似乎是违反直觉的,因为人们会认为括号至少会取消引用bar
并在赋值中抛出无效的左侧。
可以理解,当您做任何有趣的事情时,它确实会以上述方式失败。
(foo, bar) = 4
(true ? bar : foo) = 4
根据ECMA-262上的LeftHandExpressions(据我所能解释的),没有有效的非终结符会导致括号被接受。
有什么我没看到的吗?
确实是有效的。您可以在括号中包装任何简单的分配目标。
操作的左手部分=
是LeftHandSideExpression
正确识别的a。可以通过各种优先级别(NewExpression
,MemberExpression
)跟踪到a PrimaryExpression
,而这又可能是CoverParenthesizedExpressionAndArrowParameterList
:
( 表达式[In,?Yield] )
(实际上,当与target一起解析时PrimaryExpression
,它是一个ParenthesizedExpression
)。
因此,至少在语法上是有效的。JS语法是否真正有效取决于另一个因素:早期错误静态语义。这些基本上是散文或算法规则,在某些情况下会使某些产品扩展无效(语法错误)。例如,这允许作者重用数组和对象初始化程序语法进行解构,但仅应用某些规则。在赋值表达式的早期错误中,我们发现
这是一个早期的
Reference Error
,如果LeftHandSideExpression既不是ObjectLiteral也不是ArrayLiteral和IsValidSimpleAssignmentTarget的LeftHandSideExpression是false
。
我们还可以在赋值表达式的求值中看到这种区别,在赋值表达式中,将简单的赋值目标求值到可以分配给其的引用,而不用获取诸如对象和数组文字之类的解构模式。
那么IsValidSimpleAssignmentTarget对LeftHandSideExpressions做了什么?基本上,它允许对属性访问的分配,而不允许对调用表达式的分配。它没有声明任何具有自己的IsValidSimpleAssignmentTarget规则的普通PrimaryExpression。它所做的就是通过CoveredParenthesizedExpression操作提取括号之间的Expression,然后再次检查该对象的IsValidSimpleAssignmentTarget。简而言之:有效时有效。这将产生唯一的标识符(如在你的例子)和属性。(…) = …
… = …
true
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句