今天看了前端网上关于JS的题目,其中有一道题目挺有意思的。如下
1 var a = b =10; 2 (function(){ 3 var a = b = 20; 4 })(); 5 console.log(a); 6 console.log(b); 7 问:输出的 a = ? b = ?
你们想到的结果是什么?
也许绝大多数人和我一样认为是20、20 。然而答案是10、20,别急我们先来慢慢分析(*^__^*) 嘻嘻……,
1.首先第一行的 var a = b = 10; 就是用了连等操作符,连等操作符是从右向左的 所以类似于b = 10; a = b;或者是 a = (b = 10);这样的顺序进行从右向左的赋值的。
变量a是用var进行声明并赋值的所以是局部变量,但是b是未声明而直接进行赋值的所以是全局变量。所以使用连等操作符的时候要不会出现全局变量要不就是使用作用域链后端的变量。
2.从第二行开始使用匿名函数实现模仿块级作用于(私有作用域):在里面声明的变量会在函数结束后被销毁除非被外部所使用。第三行进行连等操作,先使用外部局部变量b,b =20; 然后又重新声明了一个变量a
这是一个跨级作用域重新声明的a和外部没有任何一点关系,你可以把它看成任何其它变量不如说var x;
|
然后 var a = b;初始化后的 a为20.
3.第四行声明定义一个匿名函数后随即执行,私有作用域中创建的变量a在结束后随即被销毁.所以最后改变的只有外部的变量b的值.
趁热打铁,我们再来看一道类似的连等操作赋值问题. 如下
1 想想结果是多少吧? 2 var a = {n:1}; 3 var b = a; 4 a.x = a = {n:2}; 5 问:console.log(a.x); 6 console.log(b.x);
也许有的人看到答案又疑惑的,看了上面的感觉自己掌握了,然后这道题却有出乎意料之外(⊙﹏⊙)b;
结果是,不知道有没有小伙伴答对呢.......
让我们再来分析一下
1.首先第二行声明并且使用对象字面量语法创建了一个对象,有属性n = 1;第三行声明变量b,并且把a的对象引用赋值给b。所以现在变量b和a指向的是同一个对象,即他们现在共享。
2.第四行问题来了,a.x = a = {n:2}; 先创建一个对象{n:2}并把他的引用送给变量a。因为a.x在执行前保留了对{n:1}的引用,所以给原对象增加一个属性a即对{n:2}的引用
而a现在为{n:2}并没有x的属性所以为undefined,而仍然指向原来的引用所以b.x = a;
b.x == a //true
也许讲的有点不太清楚,希望你们能说出你们的观点,也希望自己能对JS理解更深刻