JavaScript闭包(closure)

闭包是如何产生的?

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

闭包产生的条件

  • 函数嵌套
  • 内部函数引用了外部函数的数据(变量或者函数)

闭包的定义

  • 理解1:闭包是嵌套的内部函数
  • 理解2:闭包是包含被引用变量(函数)的对象

几点说明

  • 闭包存在于嵌套的内部函数中
  • 执行函数定义就会产生闭包,不用调用内部函数

闭包的应用场景

  • 将函数作为另外一个函数的返回值
  • 将函数作为实参传递给另外一个函数调用

闭包的作用

  • 使函数内部的变量在函数执行完毕后,仍然存货在内存中,延长了局部变量的生命周期
  • 让函数外部可以操作(读写)到函数内部的数据(变量/函数)

闭包的生命周期

  • 产生:在嵌套内部函数定义完成时就产生了(而不是在调用的时候产生的)
  • 死亡:在嵌套的内部函数称为垃圾对象时

闭包的缺点

  • 函数执行完成后,函数内部局部变量没有释放,占用内存时间变长(所以说:谨慎使用闭包,做到能不用就不用)
  • 容易造成内存泄漏(所以使用完闭包后要及时释放)

内存溢出

  • 定义: 一种程序运行过程中出现的错误,当程序运行需要的内存超过了剩余内存时,就会抛出内存溢出的错误
  • 产生原因: 内存泄漏积累多了就会导致内存溢出

内存泄漏

  • 产生的原因:占用的内存没有及时释放
  • 常见的内存泄漏:
  1. 意外的全局变量
  2. 没有及时清理的计时器或回调函数
  3. 没有释放的闭包

闭包的性能考量

如果不是某些特定任务需要使用闭包,在其它函数中创建函数是不明智的,因为闭包在处理速度和内存消耗方面对脚本性能具有负面影响。

例如,在创建新的对象或者类时,方法通常应该关联于对象的原型,而不是定义到对象的构造器中。原因是这将导致每次构造器被调用时,方法都会被重新赋值一次(也就是说,对于每个对象的创建,方法都会被重新赋值)。

说明:闭包的性能考量参考自 MDN

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容