题目如下:
var a={n:1}
var b=a
a.x=a={n:2}
console.log(a.x);
console.log(b.x);
这道题咋一看很简单,但你真的知道它的流程嘛?你解释了a你再解释下b啊
你把a,b都打印出来,你会发现你将迷失在赋值的过程中;甚至你不知道如何去解释……
我打印结果给你看下
console.log(a); //{n:2}
console.log(a.x); //undefined
console.log(b); {n:1,x:{n:2}}
console.log(b.x); {n:2}
问题来了:
b和a指向同一块地址,a属性内没有x,b反而有了x,这是为何?
来逐层剖析:
第一步
var a={n:1}
b=a
a指向一块{n:1}的内存,b同样指向{n:1}这块内存;内存中值不改变,a和b就不会改变
第二步
a.x=a={n:2}
ps:再强调一下,两个a的指向都是{n:1}这块内存
这种连等运算都是按照从右往左来解析的,我们把它分解开来看;
a={n:2}
{ n:2 }是一个对象,所以内存中新开辟了一块{n:2}的内存,并且 a指向修改为{n:2}
a.x=a
值得注意的的来了,前面这个a的指向依旧是{n:1}这块老内存,它暂时并没有随着a={n:2}而改变指向;
所以,这一步的赋值操作实际上是在 {n:1}
这块内存中添加了个x
的值,x等于{n:2}或者说指向{n:2}这块内存。
第三步
console.log(a.x)
这样解释就通顺多了,打印的时候,a指向{n:2}这块内存,其中没有定义x所以返回undefined
第四步
console.log(b.x)
你可能会好奇,b为什么属性那么多……
你要知道,b始终指向{n:1}这块内存地址,a改变了自身的指向,但b没有;{n:1}这块内存多了个x的属性,b自然也就多了这个属性。
b和a的关系,b从a那里获得了{n:1}这块内存地址,但它不会随着a的指向改变而改变;除非a修改了{n:1}这块内存的值,b会随着这块内存的改变而改变
在做一道简单的题,你就明白这个b为什么不会改变指向了
var obj={name:'123'}
var obj2=obj;
// obj.name='1'
// console.log(obj);
// console.log(obj2);
obj={name:'aaa'}
console.log(obj);
console.log(obj2);