请注意以下现象:spa
1 var foo = { n: 1 }; 2 var bar = foo; 3 foo.x = foo = { n: 2 }; 4 console.log(foo.x); // undefined
首先是两个变量的声明和初始化,var foo = { n: 1 }; var bar = foo;
,这个很好理解,就是foo和bar同时指向了一个相同的对象{ n: 1 }
。code
接下来,对于表达式foo.x = foo = { n: 2 };
,咱们都知道它实际上等因而foo.x = (foo = { n: 2 })
。咱们开始应用上ECMA规范上的步骤,虽然赋值运算符具备右结合性,然而它首先作的是获得表达式foo.x
的值,根据咱们对Property Accessors的解释它返回一个指向对象{ n: 1}
的x成员的引用,须要注意的是,这个时候foo并无改变引用的指向。对象
继续,开始计算右边的结果,就是让foo指向另外的一个对象{n: 2}
,返回值就是其右边运算式(operand)的结果,即对象{n: 2}
这个容易理解。blog
那么如今应该清楚了,赋值语句中foo.x
的结果是指向对象一成员x的引用,而下面的console.log(foo.x)
中的foo指向的是对象二,因此这里foo.x
返回undefined
就理所固然了。console
因此试着输出对象一,即bar(由于它从始至终指向的是对象一):class
{ n: 1, x: { n: 2 } }