美文网首页
【闭包 this 作用域】一道普普通通的测试题

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

作者: 薯条你哪里跑 | 来源:发表于2021-06-08 18:01 被阅读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指向、作用域等等问题,还是需要进一步好好消化和理解的~

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/qirjeltx.html