【问题标题】:What is output for foo.xfoo.x 的输出是什么
【发布时间】:2019-05-13 00:20:18
【问题描述】:
var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2};
foo.x 的输出是什么。
我的想法是从右到左的评价
所以它等于
foo = {n:2};
foo.x = foo
原来如此
{
n: 1
x: {n: 2}
}
但它不是,它是未定义的?我很困惑,正在寻找解释。
【问题讨论】:
标签:
javascript
operator-precedence
【解决方案1】:
这是预期的行为。见specification:
简单赋值(=)
产生式 AssignmentExpression : LeftHandSideExpression = AssignmentExpression 的评估如下:
- 设 lref 为计算 LeftHandSideExpression 的结果。
- 设 rref 为评估 AssignmentExpression 的结果。
- 令 rval 为 GetValue(rref)。
- 如果(...不重要)抛出 SyntaxError 异常
- 调用 PutValue(lref, rval)。
- 返回 rval。
简而言之,当解释器看到x = <expression> 或x.prop = <expression> 时,它首先确定要分配给什么——即LeftHandSideExpression。然后,在将右侧(AssignmentExpression)评估为一个值后,它将该值分配给最初标识为 LeftHandSideExpression 的值。所以,与
foo.x = foo = {n: 2};
foo.x 改变了原始 foo 对象,而不是重新分配的foo = {n: 2} 对象,所以在foo.x = foo = {n: 2} 行之后,foo 指的是新的{n: 2},即从未变异过。
您可以看到bar 与原始foo 引用内存中相同的对象是如何发生变异的:
var foo = {n: 1};
var bar = foo;
foo.x = foo = {n: 2};
console.log(bar);