1 2 |
var a=1,b=1; var a=b=1; |
以上两种定义方式有什么不同
1 2 3 4 5 6 |
function test1() { var a=b=1111; } test1(); console.log(a); //a is not defined console.log(b); //1111 |
b成为了全局变量。下面再看一个:
1 2 3 4 5 6 7 |
var a=1,b=2,c=3; (function(){ var a=b=1; })(); console.log(a); //1 console.log(b); //1 |
同样这个例子其实考察到闭包的问题,b=1进行了全局更改,所以最后输出了1
上面都是赋值一个常量,下面我们可以试试对象赋值的情况:
1 2 3 4 5 6 |
var a = {n:1}; var b = a; // 持有a,以回查 a.x = a = {n:2}; alert(a.x);// --> undefined alert(b.x);// --> {n:2} |
看来跟正常使用也不一样 ,本来是想更改a.n同时生成a.x。同时你可以尝试发现,上面的代码中a.x = a = {n:2};
改写成a = a.x = {n:2};
也是无济于事的,而如果最后输出一下b,它的结果就是我们开始理想的结果。So,为什么呢?
事实上,解析器在接受到 a = a.x = {n:2}
这样的语句后,会这样做:
- 找到 a 和 a.x 的指针。如果已有指针,那么不改变它。如果没有指针,即那个变量还没被申明,那么就创建它,指向 null。
a 是有指针的,指向{n:1}
;a.x 是没有指针的,所以创建它,指向 null。 - 然后把上面找到的指针,都指向最右侧赋的那个值,即
{n:2}
。
另外值得注意的是:
.
运算优先于=
赋值运算,因此此处赋值可理解为
- 声明a对象中的x属性,用于赋值,此时b指向a,同时拥有未赋值的x属性
- 对a对象赋值,此时变量名a改变指向到对象{n:2}
- 对步骤1中x属性,也即a原指向对象的x属性,也即b指向对象的x属性赋值
参考
:https://segmentfault.com/q/1010000002637728
http://justjavac.com/javascript/2012/04/05/javascript-continuous-assignment-operator.html