javascript - ecma262 中的赋值表达式

标签 javascript ecma262

考虑下面的代码

var myVar = 'Hola';
{
  let myVar;
  myVar = 'Hello'
}

在第 4 行(myVar = 'Hello')我们使用了赋值运算符

现在当我在 Assignment Operators Evaluation 中查看 ecma262 时

表示赋值运算符左边是LeftHandSideExpression,右边是AssignmentExpression

换句话说,它看起来像那样

LeftHandSideExpression = AssignmentExpression

任何人都可以向我解释 myVar 将如何评估吗? 如果它应该是 LeftHandSideExpression ?

最佳答案

要理解的主要部分是 evaluate 在这种情况下意味着我们正在为语言中的各种语法部分运行这些 Runtime Semantics: Evaluation 部分。在这种情况下

myVar = 'Hello'

如果我们看13.15.2 Runtime Semantics: Evaluation用于评估 AssignmentExpression

1.a. Let lref be the result of evaluating LeftHandSideExpression.

将深入了解各个步骤,直到您最终运行 13.1.3 Runtime Semantics: Evaluation它定义了 myVar 的评估行为。

如果你单步执行这一步,关键是 lref 不会评估为 JS 值,它评估为 Reference Record类型,这不是 JS 代码知道的值,但表示可以分配值的位置的概念。对于您的代码段,它基本上是对变量列表所在范围和变量名称的引用,因此当稍后执行赋值时,它会在稍后完全解析。

这是先评估左侧的行为,对于这样的示例更重要:

foo().bar = val();

因为评估左边意味着 foo()val() 之前运行,这是您所期望的。在这种情况下,foo() 运行,然后我们得到一个 Reference Record,将 foo() 的返回值作为赋值的目标,和 bar 作为要分配的属性名称。

回到13.15.2 Runtime Semantics: Evaluation , 我们得到

1.e Perform ? PutValue(lref, rval).

这是最终分配发生的地方。 rval"Hello" 字符串本身,因为它已被求值。如果你看一下6.2.4.6 PutValue ( V, W ) , 你可能猜到第三部分是我们最终得到的变量赋值

  • 6.a.设 base 为 V.[[Base]].
  • 6.b.断言:base 是一个环境记录。
  • 6.c.返回 ? base.SetMutableBinding(V.[[ReferencedName]], W, V.[[Strict]])

如果你是这样的话

(<scope with closest `var/let myVar`).SetMutableBinding("myVar", "Hello", false)

关于javascript - ecma262 中的赋值表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69511751/

相关文章:

javascript - DOMParser 将 &lt;script&gt; 标签附加到 <head>/<body> 但不执行

javascript - 自定义 Backbone.View undelegateEvents(),它是如何工作的?

javascript - AngularJS- ionic : create a swipeable horizonatlview which will update vertical view

javascript - ecmascript 制作中的困惑

javascript - 为什么 JSON 只允许字符串作为键?

javascript - 功能范围理解不清楚

javascript - 如何从<oj-select-one>获取选定的值?

javascript - getOwnPropertyNames 在 Firefox 上忽略 __proto__

javascript - 我应该使用哪个 ECMA-262 (ECMAScript/JavaScript) 引用?

JavaScript 闭包 - 使用 ECMA 规范,请解释闭包是如何创建和维护的