【闭包 this 作用域】一道普普通通的测试题

2021-06-08  本文已影响0人  薯条你哪里跑

题目:

var n = 2;
var obj = {
    n: 30,
    fn: (function (n) {
         n *= 2;
         this.n += 2;
         var n = 5;
         return function (m) {
             this.n *= 2;
             console.log(m + (++n));
         }
    })(n)
};
var fn = obj.fn;
fn(3);
obj.fn(3);
console.log(n,obj.n);

=======考虑下会打印出来什么=======
5
4
3
2
1

公布结果:

9
10
8 60

解析:

第一步:

先看这一段代码
fn内部是个自执行函数,所以此时内部代码已经执行,让我们按照序号看下面代码内的的备注

var n = 2;
var obj = {
    n: 30,
    fn: (function (n) {
         n *= 2;   // 2. n=2*2=4
         this.n += 2;  // 3. n为window.n,值是2*2=4
         var n = 5;   // 4.n赋值为5
         return function (m) {  // 5. 返回一个匿名函数
             this.n *= 2;
             console.log(m + (++n));
         }
    })(n)  //1. 这里的实参取的是var n = 2
};

此时 window.n = 4,并且obj.fn返回了一个匿名函数,并形成闭包内部存留n=5。继续进行

第二步:
var fn = obj.fn;  // 没有啥,把obj.fn(即上面的匿名函数) 赋值给一个新的变量
fn(3);  // 执行匿名函数

具体内部赋值如下

// 执行该函数 fn(3)
function (m) {  // 这里形参m值为传入的3
     // console.log(n) 注意这里如果打印n的话,此时n已经是5啦
        this.n *= 2;   // 执行 fn(3)是调用方为window,所以此时this.n = 4, 计算之后变为8
       console.log(m + (++n));  // 这里的n=5, 3+(++5)计算后输出9,此时n=6
 }

截止到这里控制台打印出9,此时window.n=8, 让我们继续

第三步
obj.fn(3); // 没啥执行这个函数

内部赋值如下:

function (m) {  // 这里形参m值为传入的3
      // console.log(n) 注意这里如果打印n的话,此时n已经是6啦
       this.n *= 2;   // 执行obj.fn(3)是调用方为obj,所以此时this.n = 30, 计算之后变为60
       console.log(m + (++n));  // 上一步说了n=6 , 3+(++6)  计算后输出10
 }
第四步
console.log(n,obj.n); // 输出这两个变量的值,显而易见此时n=8, obj.n = 60

总结

这道题包含了闭包、this指向、作用域等等问题,还是需要进一步好好消化和理解的~

上一篇 下一篇

猜你喜欢

热点阅读