JS 连等赋值和对象地址问题(a.x = a = {n: 2})

218 阅读1分钟

前言

群里看到有人发出的问题,觉得有价值,记录一下。

先贴代码

打开控制台,将代码执行。

let a = {n: 1}
let b = a
a.x = a = {n: 2}  
console.log(a.x) // ?{n: 2}
console.log(b.x) // ?{n: 2}

分析

估计大伙一眼看去直接就是a.x={n: 2}b.x={n: 2}了吧~

JS 引擎在执行赋值语句时,会先从左往右解析各个变量名,转换成变量值,然后从右往左执行赋值。

  1. 先解析,在a.x = a = {n: 2}中,a.x 的实际值是{n: 1}.xa 的实际值是对象 {n: 1}引用地址

  2. 再赋值,从右往左进行赋值操作,遇到第一个=a实际值修改为对象 {n: 2}引用地址,遇到第二个 = ,此时 a已经指向 {n: 2},所以真实操作是令{n: 1}.x = {n: 2}{n: 1,x: {n: 2}}

  3. 此时只省变量 b 还保持着原来对象{ n:1 }引用地址,只不过添加新成员 x,变成了{n: 1, x: {n: 2}}了;

  4. 变量 a 的实际值已经改为 对象{n: 2},所以 a.x = undefined。(辅助理解:如果使用const关键字声明 a,则会抛错,提示重复声明。)

  5. 所以

let a = {n: 1} 
let b = a 
a.x = a = {n: 2} 
console.log(a.x) // {n: 2}
console.log(b.x) // undefined

文献: