zoukankan      html  css  js  c++  java
  • 闭包:闭包理解 常见的闭包 闭包的作用 闭包的生命周期 (闭包应用:定义JS模块) 闭包的缺点 内存溢出与内存泄漏 测试题 循环遍历加监听

    闭包理解

    1.闭包的产生

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

    2.闭包到底是什么?

    廖雪峰:闭包就是携带状态的函数,并且它的状态可以完全对外隐藏起来。
    理解一(大部分人的理解):闭包是嵌套的内部函数
    理解二(少部分人的理解):包含被引用变量(函数)的那个对象(这个对象存在于嵌套的内部函数中)
    可以使用开发者工具来调试查看。

    3.产生闭包的条件?

    (1)存在函数嵌套
    (2)嵌套的内部函数必须引用在外部函数中定义的变量(函数)
    (3)外部函数被执行(内部的函数不用执行,只需要执行其函数定义就已经产生闭包)

    4.产生了几个闭包

    闭包被创建了几个,就是外部函数被执行了几次,产生了几个内部函数对象,因为闭包就是内部函数,只有执行外部函数才会去创建内部函数,和内部函数被执行几次没有关系。

    常见的闭包

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

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

    闭包的作用

    1.闭包所使用的函数内部的变量在函数执行完后,仍然存活在内存中(延长了局部变量的生命周期)
    2.让函数外部可以操作(读写)到函数内部的数据(变量/函数)

    问题:

    1.函数执行完后,函数内部声明的局部变量是否还存在?
    一般是不存在的,存在于闭包中的变量才可能存在
    2.在函数外部能直接访问函数内部的局部变量吗?
    不能,但是如果有包含这个局部变量的闭包,我们就可以通过闭包让外部操作它

    代码理解

    1.这是上面常见的闭包中的1中的代码
    2.执行fn1将会产生两个闭包,fn2和fn3
    3.第23行如果只有fn1(),是会产生两个闭包,但产生完就没了,因为fn2和fn3是局部变量
    4.第23行用f保存了fn3函数对象的引用,fn3变量是消失了,但它所指向的这个函数还存在于f中,所以这个闭包还存在
    5.第24行代码并不是说执行了fn3,fn3早没了,执行的是f,f函数和fn3一样而已
    6.就是因为4中所说的这个闭包的存在,第24行执行结果才会是1,因为fn1的变量a被保存在这个闭包中,也就体现了闭包的作用中的1(访问到了a),2(a--,操作了a),也体现了问题中的1(a还存在),2(操作了a)

    闭包的生命周期

    1.产生

    在嵌套内部函数定义执行完就产生了(不是在调用时)

    2.死亡

    在嵌套的内部函数成为垃圾对象时

    闭包应用:定义JS模块

    JS模块

    具有特定功能的js文件(特定功能:有些函数,操作一些数据)
    将所有的数据和功能都封装在一个函数内部 (私有的) (要想私有必须放到一个函数中,对象的属性是直接可见的)
    只向外暴露一个包含n个方法的对象或函数
    模块的使用者,只需要通过模块暴露的对象调用方法来实现对应的功能

    代码1

     

    代码2

     

     代码1使用先要执行函数,代码2使用起来,更直接更方便 

    闭包的缺点

    1.缺点

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

    2.解决

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

    内存溢出与内存泄漏

    1.内存溢出

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

    2.内存泄漏

    占用的内存没有及时释放
    内存泄漏积累多了就容易导致内存溢出
    常见的内存泄漏:
      意外的全局变量(在函数内部定义的全局变量,以为是局部变量)
      没有及时清理的计时器或回调函数
      闭包(没有及时释放,导致一直占用内存)

    测试题

    测试题1

    测试题2

    测试题3

    循环遍历加监听

    点击三个按钮分别显示它是第几个

    1.普通实现

    2.利用闭包实现(闭包不释放是因为闭包被按钮对象中的onclick属性引用,按钮对象是全局变量,在窗口未关闭之前不会被释放  )

    学识浅薄,如有错误,恳请斧正,在下不胜感激。

  • 相关阅读:
    平安银行Java面试-社招-五面(2019/09)
    OPPO-Java面试-社招-一面(2019/07)
    记录一次SpringBoot实现AOP编程
    Java-Long类型精度丢失问题
    微众银行Java面试-社招-一面(2019/07)
    Java-根据经纬度计算距离(百度地图距离)
    git 常用命令
    linux命令之文件、文件夹操作
    j2ee爬坑行之二 servlet
    j2ee爬坑行之一:web容器
  • 原文地址:https://www.cnblogs.com/yin-jie/p/14752856.html
Copyright © 2011-2022 走看看