闭包的原理、优点和缺点浅析

简介: 闭包指的是那些引用了另一个函数作用域中变量的函数,通常是在嵌套函数中实现的。- 《Javascript高级程序设计(第四版)》 注意:匿名函数不是闭包 一个函数和对其周围状态(lexical envi

闭包指的是那些引用了另一个函数作用域中变量的函数,通常是在嵌套函数中实现的。- 《Javascript高级程序设计(第四版)》

注意:匿名函数不是闭包

一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。 - MDN

定义

先大概了解一下,闭包,我推荐去看这篇文章,参考,Js闭包的原理(图解)- Marhoo🐝看完就懂,无需多言

这篇文章大概讲了闭包,它是引用外部作用域之后导致作用域链没有被断开,无法被 GC 的一个原因产生了闭包

注意:需要充分理解这部分知识还需要去了解一下垃圾回收,作用域链,活动对象的相关知识

注意

  1. 嵌套函数的作用链和活动对象,在外部函数执行时就会创建,闭包也就是在这个时候创建

原理

闭包的实现原理,其实是利用了作用域链的特性,在当前执行环境下访问某个变量时,如果不存在就一直向外层寻找,最终寻找到最外层也就是全局作用域,这样的一个链条就是作用域链,而闭包就是这样,它引用了另一个函数作用域中变量

闭包的优点及应用场景

优点

  1. 隐藏变量,避免全局污染
  2. 可以读取函数内部的变量

应用场景

  1. 函数防抖节流,参考函数防抖节流场景
  2. 单例模式,比如,消息提示(message)组件
  3. 模块化

闭包的缺点及解决

缺点

内存泄露

函数执行完后, 函数内的局部变量没有释放, 占用内存时间会变长,为什么没有被垃圾回收机制处理?看下面代码

function fun() {
  let a = 0;
  return function () {
    console.log(a++);
  };
}
let foo = fun();
foo();

foo 引用着 fun() 返回的匿名函数,这个匿名函数引用了另一个函数作用域中变量,产生了闭包,因此无法消除,理论上来说是因为 foo 引用匿名函数导致无法被垃圾回收,所以闭包的解决方法如下

function fun() {
  let a = 0;
  return function () {
    console.log(a++);
  };
}
let foo = fun();
foo();
foo = null;

但实际上在 node 环境中测试,手动垃圾回收后,内存并没有被回收(相关测试可以参考我的另一篇文章,掘金好像没有)

解决方法

解决闭包的方法

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

实战

结合全局对象(window)、活动对象、作用域链、闭包去思考下面的代码片段

var name2 = "The Window";
var object2 = {
  name2: "My Object",
  getNameFunc: function () {
    var that = this;
    return function () {
      return that.name2;
    };
  },
};
console.log(object2.getNameFunc()());

getNameFunc 返回的匿名函数(假设为 t)中产生了闭包,存在于 window 对象中,因为 window 调用了这个匿名函数

参考资料

  1. JavaScript中闭包的概念、原理、作用及应用 - 有鱼是只猫
  2. Js闭包的原理(图解)- Marhoo🐝
  3. 闭包实际场景应用 - qiudaoermu
  4. 设计模式-单例模式以及应用场景 - Nordon
  5. 为什么闭包不会被垃圾回收清除
相关文章
|
7月前
|
XML JSON 前端开发
前端深浅拷贝各有哪些方法,优缺点
前端深浅拷贝各有哪些方法,优缺点
77 0
|
存储 缓存 JavaScript
闭包的概念?优缺点?使用场景?
闭包的概念?优缺点?使用场景?
|
2月前
|
存储 缓存 前端开发
纯函数有哪些优点和缺点?
纯函数是指没有副作用的函数,其主要优点包括:可预测性强、易于测试和调试、支持并行计算等。但也有缺点,如可能增加内存消耗、对某些问题难以实现等。
|
1月前
|
前端开发 JavaScript
Promise有哪些缺点?如何解决这些缺点?
需要注意的是,虽然 Promise 存在这些缺点,但它仍然是 JavaScript 异步编程中的重要工具之一,并且通过合理的设计和使用,可以在很大程度上避免或减轻这些问题的影响。同时,随着技术的不断发展和进步,也会有更多更好的解决方案和模式出现,来进一步优化异步编程的体验。
|
3月前
|
数据可视化
IQR法的缺点
IQR法的缺点
112 1
|
4月前
|
数据库 索引
数据库索引的作用和优点缺点
【8月更文挑战第27天】创建索引能显著提升系统性能,确保数据唯一性,加快检索速度,加速表间连接及优化分组排序过程。然而,过度使用索引会导致创建与维护成本增加、占用更多物理空间并降低数据维护效率。因此,在创建索引时需谨慎评估需求及影响。
64 2
|
5月前
|
开发者
编程问题之逻辑编程有什么缺点
编程问题之逻辑编程有什么缺点
|
存储 Cloud Native 程序员
C++ 指针的优点及好处
C++ 指针的优点及好处
|
Java
Java多线程编程的优点和缺点
优点: 加快响应用户的时间:多线程允许并发执行多个任务,可以充分利用多核处理器,从而提高程序的性能和响应速度。比如我们经常用的迅雷下载,都喜欢多开几个线程去下载,谁都不愿意用一个线程去下载,为什么呢?答案很简单,就是多个线程下载快啊。 简化程序结构、模块化、异步化:例如我们实现电商系统,下订单和给用户发送短信、邮件就可以进行拆分,将给用户发送短信、邮件这两个步骤独立为单独的模块,并交给其他线程去执行。这样既增加了异步的操作,提升了系统性能,又使程序模块化,清晰化和简单化。 更好的资源利用:多线程可以更有效地使用计算机的资源,如CPU时间、内存和文件句柄等,提高了资源利用率。 支持并发编程:多线
781 0