JS 闭包




闭包概念


闭包就是对内部函数的叫法。( 下面代码中 inner 函数就称为闭包 )

<script>
  function outer() {
    function inner() {
    }
  }
</script>

1. 特性

(1) 闭包函数中可以读取宿主函数的变量

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>闭包</title>
</head>
<body>
<script>
  function outer() {
    let i = 100
    function inner() {
      console.log(i)
    }
    inner() // 宿主函数中调用闭包函数
  }
  outer() // 结果:100, 闭包函数成功访问宿主函数的变量 i
</script>
</body>
</html>

(2) 可以延长宿主函数变量的生命周期

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>闭包</title>
</head>
<body>
<script>
  function outer() {
    let i = 100
    return function inner() {
      console.log(++i)
    }
  }
  // 通过闭包函数, 延长了宿主函数中变量的生命周期
  let called = outer()
  called() // 结果:101
  called() // 结果:102
  called() // 结果:103

  outer()() // 结果:101
  called() // 结果:104
</script>
</body>
</html>

通过闭包,延长宿主函数中变量生命周期的常见写法,就是在宿主函数中将闭包函数返回。
然后将返回的闭包函数保存到变量上,让其函数地址始终保持引用状态无法被 GC 回收。


代码解释:
① let called = outer() 中,outer() 执行后, 返回的是闭包函数,返回的函数引用由变量 called 持有, 因为引用被持有,
所以闭包函数的信息不会被 GC 销毁, 而闭包函数又引用了宿主函数中的变量 i,所以宿主函数中的 i 也不会被销毁。

② outer()() 是比较常见的,简易调用闭包函数的写法,当不需要持有闭包函数引用,只想单纯调用一次闭包函数时
可以使用这种写法,outer()() 第一个小括号会执行 outer 函数并返回闭包函数,第二个小括号会执行前面返回的闭包函数。


2. 注意

当闭包函数内引用宿主函数变量,并且闭包函数的引用被持有时, 宿主函数的变量会一直存在于内存中,实际开发中
要避免过多的出现这种情况,或者一旦无法避免,那么请在使用后,尽快清除对闭包函数的引用,让 GC 可以释放其所占空间,
以免内存占用过大,从而影响性能或内存溢出。


应用场景示例


JS 内置函数的参数为回调函数时, 可以更优雅的为回调函数传参

需求:使用归并函数 reduce 对数组求和,并在第一次调用时,输出自定义信息

<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>闭包</title>
</head>
<body>
<script>
  let arr = [1, 2, 3, 4, 5]

  let callback = (message) => {
    return (prev, item, index) => {
      if (index === 0) {
        console.log(message)
      }
      return prev + item
    }
  }
  console.log(arr.reduce(callback('开始调用'), 0))
</script>
</body>
</html>

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值