var foo = {n:1};
var bar = foo;
foo.x = foo = {n:2}; // 或者foo = foo.x = {n:2}也不会改变结果
console.log(foo);    // {n: 2}
console.log(bar);    // {n: 1, x: {n: 2}}

为什么bar不是{n: 2,x: {n: 2}}呢?

在JS中, 首先需要明白一点,js中有5种基本类型(string/number/boolean/null/undefined), 不能对其添加自定义属性。而将对象赋值于一个变量时,其实只是让该变量的指针指向对象;
在赋值运算中, 赋值会从右向左进行,但是有一点, '.' 的运算会优先赋值, 即发生如下:

1 => foo.x = {n: 2} 即指针指向的地址不变(即非重新指向新对象), 只是对指针指向的对象添加了一个属性得到: {n: 1, x: {n: 2}}
2 => foo = {n: 2} 即foo重新指向了另一个新的对象
3 => bar的指针未有改变, 仍指向已经被添加了新属性的 {n:1, x: {n: 2}}

这一点需要和非连等区分开:

var foo = {n:1};
var bar = foo;
foo = {n: 2};
foo.x = {n: 2};
console.log(foo);    // {n: 2, x: {n: 2}}
console.log(bar);    // {n: 1}

所以,最后foo = {n: 2},bar={n:1,x: {n: 2}}
顺带一提,这也就是为什么有这么一道题:

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

b.n = 110;
console.log(a); //{n: 110}

momomomooo
67 声望4 粉丝

Write Less, Do More, Easy To Debug