本文深入分析JavaScript中连续赋值语句a.x = a = {n: 2}的执行机制。通过对比直接赋值与使用getter/setter的代码示例,揭示了该语句先获取左侧属性引用、再从右向左执行赋值的顺序。最终导致a.x为undefined而b.x指向新对象,澄清了常见的认知误区。
JavaScript连续赋值与对象引用陷阱解析
在整理面试题的过程中,遇到一段代码,其实际运行结果与直觉预期存在显著差异。
var a = {
n : 1
};
var b = a;
a.x = a = {n : 2};
console.log(a.x);
console.log(b.x);
该段代码执行后的输出结果如下:
undefined
[object Object]
初看之下,逻辑似乎应是先为变量a赋值为{n: 2},随后再将a.x赋值为{n: 2}。
然而实际情况并非如此,因此对代码进行了调整,并增加了日志输出以便观察。
var test;
var a = {
get test () {
console.log("call a get");
return test;
},
set test (value) {
console.log("call a set");
test = value;
}
}
var test2;
var b = {
get test2 () {
console.log("call b get");
return test2;
},
set test2 (value) {
console.log("call b set");
test2 = value;
}
}
a.test = {
n : 1
};
b.test2 = a.test;
console.log("begin");
a.test.x = a.test = {n : 2};
通过添加日志,可以清晰地看到该赋值语句内部具体执行了哪些操作。

这是语句执行过程中打印的日志信息。
日志显示,执行过程中先触发了一次get操作,随后触发了一次set操作。
据此推测,该语句的执行顺序为:首先取出左侧变量的引用,然后执行赋值操作(即在语句执行前,先获取对象引用,再从右向左依次执行赋值)。

以上即为本文的全部内容,希望读者能从中获得启发。