对象解构赋值:右值为对象字面量与否结果不同,是有意设计吗?
为什么这两段解构赋值代码执行结果不同?
这确实是JavaScript的有意设计,核心差异在于解构赋值的执行顺序以及右侧对象是否是被修改的目标本身。
先看第一段代码:
let obj = {}; ({a: obj.b, b: obj.a} = {a: 1, b: 2}); console.log(obj); // {b: 1, a: 2}
这里右侧的{a: 1, b: 2}是一个独立的字面量对象,JavaScript会先完整求值这个对象,再从左到右处理左侧的解构赋值:
- 把右侧对象的
a属性值1赋给obj.b - 把右侧对象的
b属性值2赋给obj.a
整个过程中右侧对象不会被修改,所以最终得到{b:1, a:2}。
再看第二段代码:
let obj = {a: 1, b: 2}; ({a: obj.b, b: obj.a} = obj); console.log(obj); // {a: 1, b: 1}
这里右侧的对象就是obj本身,解构赋值的执行逻辑变成了:
- 先处理第一个赋值项
a: obj.b:读取当前obj.a的值1,把它赋给obj.b,此时obj变成{a:1, b:1} - 再处理第二个赋值项
b: obj.a:读取当前obj.b的值(已经变成1了),把它赋给obj.a,所以obj.a还是1
因为左侧的赋值操作会直接修改右侧的对象,后续的取值会用到被修改后的属性值,最终得到{a:1, b:1}。
简单来说,当解构的右侧是独立对象时,所有取值都是基于原始对象;但如果右侧是正在被修改的同一个对象,赋值是按顺序执行的,前面的修改会影响后面的结果,这是JavaScript规范明确规定的行为。
内容的提问来源于stack exchange,提问作者Zhang Wei
相关产品推荐
相关产品推荐

