var a = {n:1};
var b = a; // 持有a,以回查
a.x = a = {n:2};
alert(a.x);// --> undefined
alert(b.x);// --> {n:2}
对于 a.x = a = {n:2}
,楼主原先的思路应该是:
- 先把
{n:2}
赋值给 a - 然后再创建 a.x,将
{n:2}
再赋值给 a.x
这样似乎确实说不通 a.x 的值是 undefined,因为 a.x 确实是被赋值了的啊。
可是事实上,a.x 的值却是 undefined。
再来看一下这个: a = a.x = {n:2}
的话,按楼主原先的思路应该是:
- 先把
{n:2}
赋值给 a.x,那么也就相当于b.x = {n:2}
啦 - 再把 a 重新指向
{n:2}
。那么这是后 a.x 的值确实是 undefined,a 对象{n:2}
中就没有 x 属性嘛。
按楼主的思路,上述两种方式的结果应该是不同的。但事实却是a = a.x = {n:2}
和a.x = a = {n:2}
的结果是一致的。所以楼主的那种赋值的思路是不对的。
事实上,解析器在接受到 a = a.x = {n:2}
这样的语句后,会这样做:
- 找到 a 和 a.x 的指针。如果已有指针,那么不改变它。如果没有指针,即那个变量还没被申明,那么就创建它,指向 null。
a 是有指针的,指向{n:1}
;a.x 是没有指针的,所以创建它,指向 null。 - 然后把上面找到的指针,都指向最右侧赋的那个值,即
{n:2}
。
所以执行以后,就有了如下的变量关系图。楼主可以慢慢体会下,想通了就很简单的。