ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

JavaScript高级重点整理(三、闭包)

2020-12-06 14:32:29  阅读:261  来源: 互联网

标签:闭包 function 函数 fn1 JavaScript 高级 内存 fn2


闭包

  1. 如何产生闭包?
    • 当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时, 就产生了闭包
  2. 注意点
    • 函数嵌套
    • 内部函数引用了外部函数的数据(变量/函数)
    • 即使外部有其他变量,只要不被引用闭包内就不会有那个值,如果内部没有引用值,也就不会有闭包。
      • 闭包存在于嵌套的内部函数中

常见的闭包

  1. 将函数作为另一个函数的返回值

    function fn1() {
        var a = 2//在这一步时闭包和a都为undefined,因为var a;只是声明
        //之后a = 2,后闭包和a同时都为2了
        function fn2() {
            a++
            console.log(a)
        }
        return fn2
    }
    var f = fn1()
    f() // 3
    f() // 4
    

    在这段代码中只生成了一个闭包,但这个闭包一直保存着引用值。

    只要调用1次fn1就会产生一个闭包,闭包的数量取决于fn1(外部函数)的调用次数

  2. 将函数作为实参传递给另一个函数调用

    function showDelay(msg, time) {
    	setTimeout(function () {
       	 alert(msg)
     }, time)
    }
    showDelay('atguigu', 2000)
    

    其中的msg就是闭包,但是time不是。

闭包的作用

  1. 使用函数内部的变量在函数执行完后, 仍然存活在内存中(延长了局部变量的生命周期)
  2. 让函数外部可以操作(读写)到函数内部的数据(变量/函数)
  3. 相当于函数暴露了一个口给我们,然后我们通过这个口来调用修改函数的局部变量(其实没有在闭包中的已经释放掉了,但是在闭包中的和局部变量保持一致),局部变量可以看做是存在于闭包里面
  4. 通过对闭包操作来达到操作内部变量的效果
    来看下面这段代码
function fn1() {
    var a = 2
    function fn2() {
        a++
        console.log(a)
        // return a
    }
    function fn3() {
        a--
        console.log(a)
    }
    return fn3
}
var f = fn1()
f() // 1
f() // 0

​ 在fn1函数执行完后,局部变量a存在于闭包没有被释放,但fn2和fn2指向的函数对象(被当做垃圾回收)fn3变量都被释放了,但是fn3指向的变量被赋给了f(赋的地址值)此时闭包也还存在。

闭包的生命周期

function fn1() {
    //此时闭包就已经产生了(函数提升, 内部函数对象已经创建了)
    var a = 2
    function fn2 () {
        a++
        console.log(a)
    }
    return fn2
}
var f = fn1()
f() // 3
f() // 4
f = null //闭包死亡(包含闭包的函数对象成为垃圾对象)

注意:如果是用 var fn2 =function (){}来定义函数的话,就要等整个函数执行完才会有闭包

闭包的缺点及解决

  1. 缺点
    • 函数执行完后, 函数内的局部变量没有释放, 占用内存时间会变长
    • 容易造成内存泄露
  2. 解决
    • 能不用闭包就不用
    • 及时释放

内存溢出与内存泄露

内存溢出:

  • 一种程序运行出现的错误
  • 当程序运行需要的内存超过了剩余的内存时, 就出抛出内存溢出的错误

内存泄露:

  • 占用的内存没有及时释放
  • 内存泄露积累多了就容易导致内存溢出
  • 常见的内存泄露:
    1. 意外的全局变量
    2. 没有及时清理的计时器或回调函数
    3. 闭包用完后没有及时处理

标签:闭包,function,函数,fn1,JavaScript,高级,内存,fn2
来源: https://blog.csdn.net/qq_45194823/article/details/110732494

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有