JasmineHua / asker

For collecting my questions.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

联等赋值

JasmineHua opened this issue · comments

var a = {n : 1}
a.x = a = {n : 2} 
console.log(a) // =>{n: 2}
a.x = {n : 2}
console.log(a) // =>{n: 2, x: Object}

按照es5规范a.x = a = {n : 2}等价于a.x = (a = {n : 2})。在(a = {n : 2})执行后a指向{n : 2}并返回{n : 2}。接着应执行a.x = {n : 2},可执行后输出a并未出现{n: 2, x: Object}的预期结果

你所看到的_a.x_和_a_只是变量名,而JavaScript引擎在解析该语句时,a.x_和_a_会被解析成变量名所引用的内存地址。
所以_a
= {n : 2} 被执行后 变量a的引用被指向了存储对象{n : 2}内存地址 而原来存储对象{n : 1}的内存地址没有发生变化
继续执行_a.x_ = a 的时候,a.x_的内存地址还是原来_a.x,虽然此时_a_的引用已经发生了变化,但是在语句解析时,_a.x_的内存地址已经被分析,它在这个过程中不会发生变化,因此_a.x_所在内存地址的引用也被指向了{n : 2},而这里的_a.x_的_a_仍然指向原来的内存地址。

var a = {n : 1}
b = a
a.x = a = {n : 2} 
console.log(b.x) // =>{n: 2}

第二行中_b_的内存地址指向了{n : 1}
在JavaScript引擎解析第三行时,事先分析_a.x_和_a_的内存地址,在执行_a_ = {n : 2}时,a_的引用从{n :1}所在的内存地址指向了{n : 2}的内存地址,而此时_a.x_的内存地址并没有发生变化,也就是说,此时_a.x_的_x_还是{n : 1}的_x。因为_b_指向{n : 1},所以_b.x_就是对象{n : 1}的_x_。

在这个过程中,总共有两个对象产生,一个是{n : 1},一个是{n : 2},这两个对象分别有自己的内存地址,我们可以把它姑且叫做N1和N2,而a、b、a.x三个变量只是对于N1、N2的引用。
a.x=a={n:2}的时候。可以看作N1.x = N1 = N2,a = {n : 2}后,a的引用地址变为N2,那么继续赋值的话,就是N1.x = N2。