var a = {n:1};a.x = a = {n:2};console.log(a.x); // 输出?答案是:console.log(a.x); // undefined不知道各位有没有答对,至少我是答错了。
var a={n:1};var b=a;a.n=2;console.log(b);//Object {n: 2}所以可以根据这个特性来测试连续赋值的顺序。var b={n:1};var a={n:1};a.n=0;console.log(b);//Object {n: 1}var b={n:1};var a=b;a.n=0;console.log(b);//Object {n: 0}var a,b;a=b={n:1};a.n=0;console.log(b);//Object {n: 0}可以看到是符合猜想2的,如果有人觉得这个测试不准确可以再来测试,使用ECMA5的setter和getter特性来测试。Object.defineProperty(window,"obj",{ get:function(){console.log("getter!!!"); }});var x=obj;obj;//getter!!! undefinedx;//undefinedObject.defineProperty(window,"obj",{ get:function(){console.log("getter!!!"); }});a=b=obj;//getter!!! undefined
通过getter再次证实,在A=B=C中,C只被读取了一次。
所以,连等赋值真正的运算规则是 B = C; A = B; 即连续赋值是从右至左永远只取等号右边的表达式结果赋值到等号左侧。
连续赋值能拆开写么?
通过上面可以看到连续赋值的真正规则,那么再回归到文章开头的那个案例,如果按照上述规则将连续赋值拆开会发现结果不一样了,如:
var a={n:1};a={n:2};a.x=a;console.log(a.x);//Object {n: 2, x: Object}所以连续赋值语句虽然是遵从从右至左依次赋值的规则但依然不能将语句拆开来写,至于为什么

按照上述过程可以看出旧的a.x和新的a都指向新创建的对象{n:2},所以他们应该是全等的。
测试:
var a = {n:1};var b = a;a.x = a = {n:2};console.log(a===b.x); //true
因为我们增加了var b=a,即将原对象增加了一条引用,所以在上述第5步时不会被释放,证实了上面的结论。
后记
通过这次了解了连续赋值的特点,再回过头看文章标题,似乎应该叫:
尽量不要使用JS的连续赋值操作,除非真的了解它的内部机制及可能会产生的后果。