# ❓ 输出以下代码的执行结果并解释为什么

var a = { n: 1 }
var b = a
a.x = a = { n: 2 }

console.log(a.x)
console.log(b.x)
1
2
3
4
5
6

首先公布答案:

undefined

{
  n: 2
}
1
2
3
4
5

然后再马后炮 💣

var a = { n: 1 } // 声明变量 a 并且赋值

var b = a // 声明变量 b 并且把 a 对象的内存地址(因为 a 是引用类型)指向 b

// 重点在这一步
a.x = a = { n: 2 }
// 整体为连续赋值 可以这么拆分
// 赋值顺序为

// a.x
// - . 运算符比 = 运算符优先级高先执行
// - 这时候 a 指向的还是 {n:1} 的内存地址,赋值声明过后 {n:1,x:undefined}
// - b 因为跟 a 指向的同一个内存地址,所以 b 也是{n:1,x:undefined}

// = a = { n: 2}
// - 同等级运算自右向左 a 被重新赋值为 {n:2} 的内存地址
// - 此时第一个 = 号前面的 a.x 是被指向过的 所以这时候指向的是 {n:1,x:undefined} 的内存地址
// - a.x 赋值过后变成 {n:1,x:{n:2}} 不要忘记 b 指向的还是这里的内存地址,a 在上一步已经发生变化指向 {n:2} 的内存地址

// 所以最后打印
// a.x 找的是 {n:2} 内存地址中的 x -> undefined
// b.x 找的是 {n:1,x:{n:2}} 内存地址中的 x -> {n:2}

console.log(a.x)
console.log(b.x)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

js 运算符优先级