浅谈js闭包

一、什么是闭包

闭包(closure)就是能够读取其他函数内部变量的函数。在js中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成 “定义在一个函数内部的函数”。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。
简单来说就是,当一个嵌套的函数内部调用了嵌套外部函数中的变量时,就会产生闭包,并且只执行外部函数(执行内部函数定义)就会产生闭包,甚至不用调用内部函数。
(闭包的最典型的应用是实现回调函数(callback) )。

二、闭包的应用

闭包的应用有将函数作为另一个函数的返回值;将函数作为实参传递给另一个函数调用
闭包的最典型的应用是实现回调函数(callback)
例子如下:

// 1. 将函数作为另一个函数的返回值
  function fn1() {
    var a = 2
    function fn2() {
      a++
      console.log(a)
    }
    return fn2//将内部函数作为返回值返回(函数也是数据,是数据就能返回)
  }var f = fn1()
  f() // 3,执行这个f()实际上是执行了f1中的内置函数
  f() // 4,闭包产生几次,就看外部函数调用几次,这里的两个f()实际上都是调用内部函数fn2()

  // 2. 将函数作为实参传递给另一个函数调用
  function showMsgDelay(msg, time) {
    setTimeout(function () {
      console.log(msg)    //闭包里面只有msg,time不在内部函数中
      alert(msg)
    }, time)
  }
  showMsgDelay('hello', 1000)

三、闭包的作用和缺点

作用

1. 使函数内部的变量在函数执行完后,仍然存在于内存中,延长局部变量的生命周期(用的太多就变成了缺点,占内存)
2. 让函数外部可以操作内部的数据(变量、函数)
3. 逻辑连续,当闭包作为另一个函数调用的参数时,避免你脱离当前逻辑而单独编写额外逻辑
4. 方便调用上下文的局部变量
5.加强封装性,可以达到对变量的保护作用,保护函数内的变量安全

缺点

函数执行完以后,内部局部变量没有释放,占用内存,容易造成内存泄漏,因此能不用闭包就不用,或者及时释放(很重要)

回收例子如下:

function fn1() {
    var arr = new array[100000]
    function fn2() {
      console.log(arr.length)
    }
    return fn2;
  }
  var f = fn1();
  f();
  f = null // 让内部函数成为垃圾对象-->回收闭包,清除引用

问题:
函数执行完后,函数内部声明的局部变量是否存在?
答:一般不存在,存在于闭包中的变量才“可能”存在(即存在引用关系,引用了外部变量)
函数外部可以直接访问到内部的局部变量吗?
答:不能,但是可以通过闭包来操作

四、闭包的生命周期

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

死亡:嵌套的内部函数成为垃圾对象时

 function fn1() {
    //此处闭包已经产生(函数提升,内部函数对象已经创建)
    var a = 3
    function fn2() {   //若写成var fn2 = function (){...},则是在此处(函数定义完)产生
      a++
      console.log(a)
    }
    return fn2
  }
  var f = fn1()
  f()//3
  f()//4   //在这里闭包还未死亡
  f = null //此时闭包对象死亡(包含闭包的对象成为垃圾对象),引用fn1的变量不再引用它
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值