由一道面试题,引发了这篇文章。
var a = {n: 1};① var b = a;② a.x = a = {n: 2};③ console.log(a);④ console.log(b);⑤ console.log(a.x);⑥ console.log(b.x);⑦
①在栈中创建变量a,然后在堆中创建{n:1},再将变量a指向堆中的{n:1}的地址
②在栈中创建变量b,然后将变量b指向堆中的a的地址
此时①和②之间存在引用关系,即a变量中的对象发生了变化,b也同时发生了变化,因为他们所指向的是同一个地址
③这里要注意了一个点就是,执行顺序的问题,即用【.】的方法执行顺序大于【=】赋值
3.1 所以,会先执行a.x,即a中添加对象x,变成a={n:1,x:undefined}
3.2 往后执行a={n:2},这时候的变量a的值变成了a={n:2},同时断开了b的引用,因为此时的变量a是被重新赋值一个开辟了一个新的内存地址。(这里涉及到的知识点有:执行顺序(运算符优先级),js的垃圾回收机制(标记-清除算法))
3.3 然后就是a.x赋值为上面【3.2】点的值,变成 a.x={n:2}
④输出{n:2}
⑤输出{n:1,x:{n:2}}
⑥输出undefined
⑦输出{n:2}
面试题2:
function fun(){ var a = b = 5; } fun(); //这也是连续赋值的一个问题,方法执行后,b成了全局变量,a因为是局部变量所以无法访问到 alert(typeof a); // --> undefined alert(typeof b); // --> number