JS 随记-好题(1)

205 阅读2分钟

涉及到引用对象赋值 以及 运算符的优先级

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

a.x 	// 这时 a.x 的值是多少
b.x 	// 这时 b.x 的值是多少

刚开始看到这道题,觉得这两个答案会是{n: 2}。但是在控制台运行了一下,结果却是undefined{n: 2}

一直在纠结为什么a.x是undefined,经过查找资料终于明白了,所以记录一下。

下面来分析一下:

首先

var a = {n: 1};
var b = a;

解析:在这里变量a指向了一个对象{n: 1},为了方便分辨,将其称为对象A。b指向了a所指向的对象,实际上是通过浅拷贝,变量b现在的值是访问对象A的地址。

重点 a.x = a = {n: 2};

解析:js的赋值运算顺序永远都是从右往左的,但是由于“.”是优先级最高的运算符,所以这行代码先“计算”了a.x。此时a指向的对象{ n : 1 }新增了属性 x,此时 x 还为赋值即为 undefined 。

从图上可以看到,由于 b 跟 a 一样是指向对象 A 的,要表示 A 的 x 属性除了用 a.x,自然也可以使用 b.x 来表示了。

接着,依循“从右往左”的赋值运算顺序先执行 a={n:2} ,这时候,a指向的对象发生了改变,变成了新对象{n:2}(我们称为对象B)

接着继续执行 a.x=a,由于( . 运算符最先计算)一开始 js 已经先计算了 a.x,便已经解析了这个 a.x 是对象 A 的 x,所以在同一条公式的情况下再回来给 a.x 赋值,也不会重新解析这个 a.x 为对象 B 的 x。

所以 a.x=a 应理解为对象 A 的属性 x 指向了对象 B:

所以,当console.log(a.x)的时候,a 是指向对象 B 的,但对象 B 没有属性 x。(当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止。但当查找到达原型链的顶部 -- 也就是 Object.prototype ,仍然没有找到指定的属性B.prototype.x ,自然也就输出undefined

console.log(b.x)的时候,由于 b.x 表示对象A的x属性,该属性是指向对象B,自然也输出了{n:2}。

参考链接:www.cnblogs.com/vajoy/p/370…