JavaScript语法函数高级之闭包

一、闭包定义

1、定义:
当函数能够记住(外部作用域可能不存在)并且访问自己的作用域链时就会产生闭包。
2、闭包本质上是一个c++对象,管理内部函数依赖于外部环境的数据。

<script type="text/javascript">

        /*闭包定义
         *  闭包:当函数发生嵌套时,如果内部函数引用了外部函数的变量时,就会产生闭包
                闭包是一个js引擎创建的c++对象,用来管理一些数据,内部函数引用了外部函数的数据
                  闭包(标准定义):当函数能够记住并且访问自己的作用域链时就会产生闭包 。
                  如何解释闭包的定义?伪闭包和闭包的两种情况。
                 常见的闭包
                a. 将函数作为另一个函数的返回值
                b. 将函数作为实参传递给另一个函数调用      
                 */
        function wrap() {
            var a = 1;
            var b = 2;

            function inner() {
                console.log(a);
                console.log(b);
            }
            //常见闭包:1、将函数作为另一个函数的返回值
            return inner;
        }
        var c = wrap();
        c();

        // 常见闭包: 2. 将函数作为实参传递给另一个函数调用
        function showMsgDelay(msg, time) {
            setTimeout(function() {
                console.log(msg)
            }, time)
        }
        showMsgDelay('hello', 1000)
    </script>

二、产生闭包的条件

当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时, 就产生了闭包。

  • a. 函数嵌套
  • b. 内部函数引用了外部函数的数据(变量/函数)
  • c. 调用外部函数

三、常见的闭包

        a. 将函数作为另一个函数的返回值
        b. 将函数作为实参传递给另一个函数调用

四、闭包作用

闭包作用: 延长包裹函数的生命周期;让包裹函数的外部可以读到包裹函数内部的数据。

<!--闭包作用
        1. 延长了包裹函数局部变量的生命周期
        2. 让包裹函数外部读写到包裹函数内部的数据   -->
    <script type="text/javascript">
        function wrap(){
            var a=1;
            var b=2;
            function inner(){
                console.log(a);
                console.log(b);
            }
        }
        var inner=wrap();
        inner();

    </script>

五、闭包生命周期

闭包创建: 闭包 是包裹函数的执行上下文被创建时,即包裹函数被调用时创建。
闭包销毁:手动将内部函数置为null.

<!--
          闭包生命周期:
       创建: 闭包 是包裹函数的执行上下文被创建时,即包裹函数被调用时创建。
       销毁:手动将内部函数置为null.
            闭包什么时候被收回?
                当闭包的引用计数为0的时候,自动被收回
       -->
    <script type="text/javascript">
        function wrap() {
            var a = 1;
            var b = 2;
//          debugger
            function inner() {
                console.log(a);
                console.log(b);
            }
            return inner;
        }
        //闭包是由wrap函数创建,由wrap包裹函数将闭包交给inner函数的作用域
        var c = wrap(); //创建闭包
        c();
        c=null;//销毁闭包
    </script>

六、闭包缺点:内存泄漏

    <!--内存泄漏&内存溢出
            内存溢出:指的是程序向系统申请一定大小内存,而系统不能满足程序的要求就是内存的溢出。
           内存泄漏:指申请的内存一直得不到释放,GC回收不了。一般在项目中就是,你声明的变量一直保存在内存中,它有值但你把它的引用地址搞丢了一直没法用它,而GC又没法回收这块内存给别的程序使用就叫内存泄漏。
           -->
    <script type="text/javascript">
        function wrap(){
            var a=1;
            var b=2;
            function inner(){
                console.log(a);
                console.log(b);
            }
        }
        var inner=wrap();
        inner();
//      虽然使用inner=null可以销毁闭包,但是在开发中,代码量大,不容易确定在何处销毁,一般不做销毁处理,因此导致了内存溢出.
        inner=null;//销毁闭包
    </script>

七、 伪闭包(鸡肋闭包)

不是必须创建闭包,通过变量查询也可以实现变量值获取,却创建了闭包。

<!--伪闭包(鸡肋闭包):不是必须创建闭包,通过变量查询也可以实现变量值获取,却创建了闭包-->
    <script type="text/javascript">
        function wrap(){
            var a=1;
            var b=2;
            function inner(){
                console.log(a);
                console.log(b);
            }   
             inner();
        }

        wrap();

    </script>

八、闭包应用——模块化

定义JS模块:
1. 具有特定功能的js文件
2. 将所有的数据和功能都封装在一个函数内部(私有的)
3. 只向外暴露一个包信n个方法的对象或函数
4. 模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能

<body>
<!--
    闭包的应用2 : 定义JS模块
      * 具有特定功能的js文件
      * 将所有的数据和功能都封装在一个函数内部(私有的)
      * 只向外暴露一个包信n个方法的对象或函数
      * 模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能
-->
<script type="text/javascript" src="05_coolModule.js"></script>
<script type="text/javascript">
  var module = coolModule()
  module.doSomething()
  module.doOtherthing()


  var module2 = coolModule()
  module2.doSomething()
  module2.doOtherthing()

</script>

九、闭包缺点

1、缺点

  • 函数执行完后, 函数内的局部变量没有释放, 占用内存时间会变长
  • 容易造成内存泄露

2、 解决

  • 能不用闭包就不用
  • 及时释放

十、使用细节和注意事项:

1、闭包创建个数与包裹函数的调用次数有关。

<script type="text/javascript">
        function wrap() {
            var a = 1;
            var b = 2;

            function inner() {
                console.log(a);
                console.log(b);
            }
            return inner;
        }
        //闭包创建个数与包裹函数的调用次数有关
        var c = wrap();
        var cc =wrap();
        var ccc =wrap();
        ccc();
        cc();
        c();
    </script>

2、闭包创建后存放:在内部函数的作用域中。
3、闭包使用:内部函数调用时使用。
4、闭包缺点:内存泄漏。
5、包裹函数创建的闭包是和内部函数一一绑定关系。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值