js连等赋值

2,924 阅读2分钟
var a = { n: 1 };  
var b = a;a.x = a = { n: 2 };  
console.log(a.x); // --> undefined  
console.log(b.x); // --> {n:2}

预热

关联性:

关联性决定了拥有相同优先级的运算符的执行顺序。

(a OP b) OP c

左关联既把左右的子表达式加上小括号,右关联同理。

赋值运算符:

  • 赋值运算符是右关联
  • 赋值运算符的返回结果就是赋值运算符右边的那个值

栗子:

a = b = 5;

b 被赋值为5,然后a也被赋值为b = 5 的返回值,也就是5,所以a b 都为5

成员属性运算符:

  • 左关联

运算符优先级:

运算符的优先级决定了表达式中运算执行的先后顺序。

常用运算符优先级: 圆括号>成员属性>后置递增递减>逻辑非>前置递增、typeof>逻辑与/或>赋值

代码分析1:

var a = { n: 1 };    // 声明变量a,并在内存中创建了一个新对象,a指向这个新对象的地址
var b = a;            // 声明变量b,并把a的地址赋值给变量b,所以ba指向同个地址

代码分析2:

a.x = a = { n: 2};  
  1. 因为成员属性运算符的运算优先级大于赋值运算符,所以先执行a.x(step1),但是a对象并没有x属性,所以a.x等于undefined并等待赋值运算,a还是指向旧地址#001

  2. 赋值运算符是右关联性的,所以执行a = { n: 2 }(step2),这时候a的地址发生了变化,指向了新地址#002,因为b还保留着a的旧地址,所以旧地址没被释放掉。

  3. a.x = a = { n: 2 },可以理解为a.x被赋值为a = { n: 2 } 的返回值,既{ n: 2 }。第一个=号右边的a已经指向了新地址,而第一个等=号左边的a还是旧地址。因为先执行a.x(step1),这时候的a还是指向旧地址,然后等step2执行完之后执行a.x = step2的返回值(step3)。

所以 a = { n : 2 }; b = { n: 1; x: { n: 2 } };

a.x = undefined;

b.x = { n: 2 };