今天看了前端网上关于 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 理解更深刻
来源: http://www.cnblogs.com/fansama/p/6648956.html