javascript - ecma262中的赋值表达式
问题描述
考虑以下代码
var myVar = 'Hola';
{
let myVar;
myVar = 'Hello'
}
在第 4( myVar = 'Hello'
) 行,我们使用了赋值运算符
现在,当我在赋值运算符评估中查看 ecma262 时
它说赋值运算符的左侧是LeftHandSideExpression,右侧是AssignmentExpression
换句话说,它看起来像那样
LeftHandSideExpression = 赋值表达式
谁能向我解释 myVar 将如何被评估?如果它应该是 LeftHandSideExpression ?
解决方案
要理解的主要部分是,evaluate
在这种情况下,意味着我们正在Runtime Semantics: Evaluation
为语言中的各种语法片段运行这些部分。如果是
myVar = 'Hello'
如果我们看一下13.15.2 运行时语义:评估AssignmentExpression
行的评估
1.a. 令 lref 为评估 LeftHandSideExpression 的结果。
将深入了解各个步骤,直到您最终运行13.1.3 运行时语义:评估,它定义了myVar
.
如果您逐步执行此操作,关键是它lref
不会评估 JS 值,而是评估Reference Record
类型,这不是 JS 代码知道的值,而是表示可以分配值的位置的概念。就您的代码片段而言,它基本上是对变量列表的范围和变量名称的引用,因此稍后执行分配时,稍后会完全解析。
这是首先评估左侧的行为,对于像这样的示例更重要:
foo().bar = val();
因为评估 left 意味着foo()
运行 before val()
,这是您所期望的。在这种情况下foo()
运行,然后我们得到一个Reference Record
带有返回值的foo()
作为赋值的目标,并bar
作为要赋值的属性名称。
回到13.15.2 运行时语义:评估,我们开始
1.e 执行?放置值(lref,rval)。
这是最终分配发生的地方。rval
是"Hello"
字符串本身,因为它已被评估。如果您查看6.2.4.6 PutValue (V, W),您可能会猜到第三部分是我们最终得到的变量赋值
- 6.a. 设基数为 V.[[Base]]。
- 6.b。断言:base 是一个环境记录。
- 6.c。返回 ?base.SetMutableBinding(V.[[ReferencedName]], W, V.[[Strict]])
所以在你的情况下
(<scope with closest `var/let myVar`).SetMutableBinding("myVar", "Hello", false)
推荐阅读
- python - How to properly test pcollection length when unit testing Apache Beam
- python-3.x - 为什么我的嵌入图像不总是显示?
- elasticsearch - Merge / flatten sub aggs into main agg
- php - 从供应商文件夹重新生成 composer.lock
- json - pyspark flat csv 到 mongodb 中的嵌套 json
- php - 根据查询结果更改行标题而不进行多次查询
- reactjs - Cellrenderer 和 react-router-dom 链接
- c# - 自定义授权过滤器在 ASP.NET Core 3 中不起作用
- r - 使用 reorder_within 后将轴标签中的项目加粗
- r - R:错误:在 dplyr 中使用 unnest 时长度不兼容