什么是闭包?闭包的用途是什么?闭包的缺点是什么?

什么是闭包?闭包的用途是什么?闭包的缺点是什么?

1.什么是闭包

理解闭包,首先必须理解变量作用域。JavaScript 有两种作用域:全局作用域和函数作用域。函数内部可以直接读取全局变量。

下面代码中,函数f1可以读取全局变量n。

var n = 111;
function f1() {
  console.log(n);
}
f1() //111

函数f1内部声明的变量n,函数外是无法读取的。

如果出于种种原因,需要得到函数内的局部变量。只有通过变通方法才能实现。那就是在函数的内部,再定义一个函数。
function f1() {
  var n = 111;
  function f2() {
  console.log(n); // 111
  }
}

上面代码中,函数f2就在函数f1内部,这时f1内部的所有局部变量,对f2都是可见的。但是反过来就不行。这就是 JavaScript 语言特有的”链式作用域”结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。

既然f2可以读取f1的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!

function f1() {
  var n = 111;
  function f2() {
    console.log(n);
  }
  return f2;
}
var result = f1();
result(); // 111

上面代码中,函数f1的返回值就是函数f2,由于f2可以读取f1的内部变量,所以就可以在外部获得f1的内部变量了。

简言之,如果一个函数用到了外部的变量,那么该函数和这个变量就叫做闭包。

2.闭包的用途是什么?

用途:

  1. 可以从外部读取函数内部的变量
  2. 让这些变量始终保持在内存中
  3. 封装对象的私有属性和私有方法。
2.1可以从外部读取函数内部的变量,代码如下:
function f1(){
    var n=666;
    function f2(){
        console.log(n);
    }
    return f2;
}
var resule=f1();
resule()  ///666
2.2闭包使得内部变量记住上一次调用时的运算结果,代码如下:
function f1(n) {
  return function () {
    return n++;
  };
}
var a1 = f1(1);
a1() // 1
a1() // 2
a1() // 3
var a2 = f1(5);
a2() // 5
a2() // 6
a2() // 7

上面代码中,n是函数f1的内部变量。通过闭包,n的状态被保留了,每一次调用都是在上一次调用的基础上进行计算。从中可以看到,闭包a1/a2使得函数f1的内部环境,一直存在。所以,闭包可以看作是函数内部作用域的一个接口。

为什么会这样呢?原因就在于a1/a2始终在内存中,而a1/a2的存在依赖于f1,因此也始终在内存中,不会在调用结束后,被垃圾回收机制回收。这段代码中,a1 和 a2 是相互独立的,各自返回自己的私有变量。

3.闭包的优缺点是什么?

优点:
闭包的优点是可以避免全局变量的污染;

缺点:
1.外层函数每次运行,都会生成一个新的闭包,而这个闭包又会保留外层函数的内部变量,所以内存消耗很大。因此不能滥用闭包,否则会造成网页的性能问题.在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

2.闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
闭包是指一个函数能够访问并操作其词法作用域外部的变量的能力。闭包通过捕获外部函数的变量和参数,使得这些变量和参数在函数执行完毕后仍然可以被访问和使用。 闭包的优点包括: 1. 数据隐藏和封装:闭包可以隐藏内部变量和函数,只暴露需要暴露的接口,提供了更好的数据安全性和封装性。 2. 保持状态:闭包可以保持函数执行时的状态,使得函数可以记住之前的操作和结果,方便实现一些需要记忆的功能。 3. 延长变量的生命周期:闭包可以使得变量在函数执行完毕后仍然存在,不会被垃圾回收机制回收。 闭包缺点包括: 1. 内存占用:闭包会导致外部变量一直存在于内存中,可能会占用较多的内存空间。 2. 性能问题:由于闭包涉及到作用域链的查找,可能会导致函数执行速度变慢。 闭包的使用场景包括: 1. 保持状态:闭包可以用于实现记忆功能,例如实现一个计数器或缓存函数的结果。 2. 数据隐藏和封装:闭包可以用于实现模块化的代码结构,隐藏内部实现细节,只暴露必要的接口。 3. 回调函数:闭包可以用于实现回调函数,将函数作为参数传递给其他函数,并保持对外部变量的访问。 综上所述,闭包是指一个函数能够访问并操作其词法作用域外部的变量的能力。它具有数据隐藏和封装、保持状态和延长变量生命周期的优点,但也可能导致内存占用和性能问题。闭包适用于保持状态、数据隐藏和封装以及回调函数等场景。 #### 引用[.reference_title] - *1* [什么是闭包?有哪些使用场景?优缺点是什么?](https://blog.csdn.net/qq_33505829/article/details/86080460)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [闭包的定义,原理,应用场景,优点,缺点](https://blog.csdn.net/weixin_52148548/article/details/126916799)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值