今天逛群发现有同学问了这么一个问题
其实这道题目的难点并不在引用类型相关知识点,而是在运算符优先级
先给出解答
var a = {n: 1};
var b = a;
a.x = a = {n: 2};
console.log(a.x); // undefined
console.log(b.x); // {n:2}
主要难点在于对第三行 a.x = a = {n: 2} 的理解
- 明确 . 运算符优先级远远高于 = 运算符,MDN相关文档
- 明确 a = b = c = d = 7 的运算过程
- d 被赋值为 7 ,d = 7 的返回值为7
- c 被赋值为 d = 7 的返回值7
- b 被赋值为 c = 7 的返回值7
- a 被赋值为 b = 7 的返回值7
- 整个表达式的返回值为7
- 所以对于 a.x = a = {n: 2}
- 第一步执行 a.x —— 为a对象创建x属性,此时x属性的值是undefined,但是请注意此时的a对象和b对象的指针地址是相同的
a.x === b.x // true
所以 b.x 的值是 {n: 2}
此时a.x返回值为undefined - 第二步执行 a = {n: 2} —— 注意在这一步 a对象指向了新地址,且返回值为{n: 2}
- 第三步执行 undefined = {n: 2}
- 第一步执行 a.x —— 为a对象创建x属性,此时x属性的值是undefined,但是请注意此时的a对象和b对象的指针地址是相同的
- 所以最后的 a.x 是在被指向了新地址后的a的属性,因未被赋值过,自然是undefined
综上所述,a.x = a = {n: 2} 的运算过程可拆分为
a.x = a = {n: 2};
undefined = a = {n: 2} // a.x 返回了 undefined,此时a.x的值也是undefined
undefined = {n: 2} // a = {n: 2} 返回了 {n: 2},此时a对象指向了新指针
{n: 2} // undefined = {n: 2} 返回了 {n: 2}
所以,将 a.x = a = {n: 2} 换成 a = a.x = {n: 2} 效果相同
a = a.x = {n: 2}
a = undefined = {n: 2} // a.x 返回了 undefined ,此时a.x的值也是undefined
a = {n: 2} // undefined = {n: 2} 返回了 {n: 2},此时a对象指向了新指针
{n: 2} //a = {n: 2} 返回了 {n: 2},此时a对象指向了新指针