闭包


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 官方解释
        // 一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),
        // 这样的组合就是闭包(closure)。

        // *这里的词法环境是指定义这个函数的外部词法环境

        // 闭包:
        //                 闭包的条件:
        //                     - 函数嵌套函数
        //                     - 内部函数使用外部函数的变量
        //                     - 调用外部函数

        //                 闭包到底是什么:
        //                     - 通俗的理解:函数内部嵌套的函数
        //                     - 浏览器查看后理解:内部函数的Scopes中,包含引用外部函数变量的一个对象

        //                 闭包的作用:
        //                     - 延长了局部变量的生命周期
        //                     - 保护局部变量
        //                     - 封装代码


        //                 闭包的缺点:
        //                     - 局部变量会长期驻留在内存中,可能会造成内存泄漏(IE9以下)

        //                 解决闭包带来的缺点:
        //                     - 减少使用闭包
        //                     - 及时释放



        // var fn = function () {
        //     var count = 0;

        //     console.log(count);

        //     return function () {
        //         return ++count;
        //     };
        // };

        // var use = fn();

        // setInterval(() => {
        //     console.log('asdas');
        // }, 0);


        // //例子2 返回闭包(函数和词法环境引用)给bb
        // var bb = (function () {
        //     var a = new Array(1000000).join('a');//将a存储在堆内存
        //     var b = new Array(1000000).join('b');//不存堆内存
        //     var c;
        //     // c = c + a; 无法累加堆内存
        //     return function () {
        //         console.log(a);//调用累加 输出

        //         c = c + a; //能累加堆内存
        //         console.log(c);//输出累加
        //     }
        // })()

        // bb();


        //1.创建全局上下文 全局变量bb
        //2.执行匿名函数 创建函数上下文 函数变量a b c
        //3.返回闭包(函数和词法环境)给bb 被引用的部分(a,c)没有被释放 函数上下文结束

        //4.执行bb 创建函数上下文
        //5.函数上下文内根据闭包(内部匿名函数和词法的引用)调用 a c
        //6.闭包环境结束 函数上下文结束 全局上下文结束

        //函数上下文结束 全局上下文结束





        //例子3 阿里面试题
        // function A(a) {
        //     A = function (b) {
        //         console.log(a + b);
        //     }
        //     console.log(a);
        // }

        // A(new Array(1000000).join('x'));//此时A变成闭包 形参a的值 也就是new Array(1000000).join('x') 得不到释放
        // A(new Array(1000000).join('Q'));//执行之后函数作用域没有东西被外部占用 不会形成新闭包 但第一次传入形参a的值依然包含在词法环境中得不到释放




        // var c = (function () {
        //     var a = new Array(100000000).join(1);
        //     function A() {
        //         a = a + new Array(1000).join(1);
        //         console.log(a);
        //     }
        //     return A;
        // })();

        // A(new Array(1000000).join('x'));//此时A变成闭包 形参a的值 也就是new Array(1000000).join('x') 得不到释放
        // A(new Array(1000000).join('Q'));//执行之后函数作用域没有东西被外部占用 不会形成新闭包 但第一次传入形参a的值依然包含在词法环境中得不到释放


        for (var i = 0; i < 10; i++) {
            (function (o) {
                setTimeout(() => {
                    console.log(o)
                })
            })(i)

        }










    </script>

</body>

</html>

文章作者: iamfugui
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 iamfugui !
评论
  目录