美文网首页
图解 | 理解闭包

图解 | 理解闭包

作者: 鲸鲸景鲸叻 | 来源:发表于2020-03-29 16:10 被阅读0次

    文 / 景朝霞

    来源公号 / 朝霞的光影笔记

    ID / zhaoxiajingjing

    图 / 自己画

    ❥❥❥❥点个赞,让我知道你来过~❥❥❥❥


    前情提要:

    1. 题目 | let和var的区别(一、二)
    2. 图解 | let和var的区别(一、二)
    3. 题目 | 带VAR和不带VAR的区别
    4. 图解 | 带VAR和不带VAR的区别
    5. 总结 | LET和VAR区别(三、四)
    6. 图解 | 作用域和作用域链
    7. 练习题 | 作用域和作用域链

    0 / 看图说话

    var n = 1;
    function fn(){
        var n = 2;
        function f(){
            n--;
            console.log(n);
        }
        f();
        return f;
    }
    var x = fn();
    x();
    console.log(n);
    
    公号ID:zhaoxiajingjing

    △ 画简版的,不用的会出栈销毁

    创建函数

    1. 开辟一个堆内存
    2. 把函数体中的代码以字符串格式存到堆内存中
    3. 把堆内存的地址赋值给函数名/变量名
    4. 函数在哪创建的,在执行时需要查找的上级作用域就是谁。即:FN[scope]:VO(G) F[scope]:AO(FN)

    函数执行

    1. 开一个全新的栈内存:执行上下文EC(xx),会形成一个全新的私有作用域AO(xx)
    2. 形参赋值,变量提升(形参和在私有作用域中声明的变量:私有变量)
    3. 代码执行,把堆内存的代码字符串一行行拿出来运行
    4. 遇到变量:作用域链查找机制,找到它。
      • 看它是否为自己当前执行上下文/私有作用域下的私有变量
      • 是私有的,拿来用即可
      • 不是自己私有的,沿着scopeChain作用域链向上级作用域查找。
      • 上级作用域,如果有该变量,拿来用;如果没有该变量,再沿着作用域链向上级作用域查找
      • 一直找到全局作用域为止
    5. <u>私有变量和外界的变量没有必然关系,可以理解为被私有栈内存保护起来了,这种机制就是闭包保护机制</u>

    其中,EC(FN) 执行上下文在执行完后,返回了一个小函数f,外面的x接收了小函数f的地址。那么,EC(FN)执行上下文/私有作用域中有东西被外界占用了,所以不会被销毁。

    1 / 闭包

    来~再念一遍:

    <u>函数执行会形成一个全新的私有作用域,保护里面的变量不受外界干扰,这种保护机制就称为闭包。</u>

    但是,我们经常听到这样说的:

    函数执行会形成一个私有作用域,而这个栈内存不销毁,这样里面的私有变量与外面的不冲突,并且能保存这些值,叫做闭包。

    这种说法呢,只把不销毁而留下来的称为闭包。

    但,我理解的是当它形成了就已经是闭包了,这两种说法都OK,看个人理解认为哪种都OK。

    闭包有两个作用:保护、保存

    • 保护:保护私有变量不让外界干扰,与外界没有必然联系
    • 保存:形成一个不销毁的私有作用域,私有栈内存里面的东西会保存下来;以后它里面的东西还能被调用到

    2 / 练习题

    请画图理解:作用域链查找机制、闭包机制。像上图画简单的即可。

    1. 输出结果是?fn函数执行完后是否会销毁?
    console.log(a, b);
    var a = 12,
        b = 12;
    function fn(){
        console.log(a, b);
        var a = b = 13;
        console.log(a, b);
    }
    fn();
    console.log(a, b);
    

    注意:

    var a = 12,
        b = 12;
    // 等价于
    var a = 12;
    var b = 12;
    
    var a = b = 1;
    // 等价于
    var a = 1;
    b =1;
    
    1. 输出结果是什么?哪些执行完后不会销毁?为什么?
    var i = 20;
    function fn(){
        i -= 2;
        return function (n) {
            console.log(++i-n):
        };
    }
    var f = fn();
    f(1);
    f(2);
    fn()(3);
    fn()(4);
    f(5);
    console.log(i);
    
    1. 输出结果是?
    var i = 0;
    function A(){
        var i = 10;
        function x(){
            console.log(x);
        }
        return x;
    }
    var y = A();
    y();
    function B(){
        var i = 20;
        y();
    }
    B();
    

    3 / 预告

    如何判断THIS?

    △ 文章首发,ID :zhaoxiajingjing

    相关文章

      网友评论

          本文标题:图解 | 理解闭包

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