JavaScript高级day29~33--函数中的闭包

本文深入探讨JavaScript中的闭包,包括其产生、作用、常见形式及生命周期。通过实例解析如何利用闭包实现按钮点击显示序号的功能,阐述闭包在延长局部变量生命周期和外部访问内部数据中的关键作用。同时,讨论了闭包相关问题,如变量存续和外部访问限制,并详细解释了闭包的生命周期。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0. 闭包引入

需求: 点击某个按钮, 提示"点击的是第n个按钮"

先准备三个按钮:

<body>
<button>测试1</button>
<button>测试2</button>
<button>测试3</button>
</body>

利用遍历加监听实现:

 var btns = document.getElementsByTagName('button')
  //遍历加监听
for (var i = 0,length=btns.length; i < length; i++) {//length=btns.length避免多次计算length
    var btn = btns[i]
    //将btn所对应的下标保存在btn上
    btn.index = i
    btn.onclick = function () {
      alert('第'+(this.index+1)+'个')
    }

在这里插入图片描述

或者也可以采用匿名函数自调用的方式:
即 (function (){})()的格式

for (var i = 0,length=btns.length; i < length; i++) {
  //闭包
    (function (j) {
      var btn = btns[j]
      btn.onclick = function () {
        alert('第'+(j+1)+'个')
      }
    })(i)
  }

在这里插入图片描述

1. 如何产生闭包?

  • 当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时, 就产生了闭包
    在这里插入图片描述

2. 闭包到底是什么?

  • 使用chrome调试查看
  • 理解一: 闭包是嵌套的内部函数(绝大部分人)
    在这里插入图片描述
  • 理解二: 包含被引用变量(函数)的对象(极少数人)

在这里插入图片描述

  • 注意: 闭包存在于嵌套的内部函数中(理解一和理解二共存)

3. 产生闭包的条件?

  • 函数嵌套
  • 内部函数引用了外部函数的数据(变量/函数)
  • 在调用外部函数,执行内部函数定义时就产生了闭包,不用调用内部函数

4. 常见的闭包

将内部函数作为外部函数的返回值
在调用闭包函数时,实际上在执行内部函数

  // 1. 将函数作为另一个函数的返回值
  function fn1() {
    var a = 2
    function fn2() {
      a++
      console.log(a)
    }
    return fn2
  }
  var f = fn1()
  f() // 3  实际是在执行fn2 调用内部函数
  f() // 4

将函数作为实参传递给另一个函数调用
msg调用了外部函数

 // 2. 将函数作为实参传递给另一个函数调用
  function showDelay(msg, time) {
    setTimeout(function () {
      alert(msg)
    }, time)
  }
  showDelay('atguigu', 2000)

在这里插入图片描述

5.闭包的作用

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

6. 闭包相关的问题

  1. 函数执行完后, 函数内部声明的局部变量是否还存在?
    一般是不存在, 存在于闭包中的变量才可能存在
  1. 在函数外部能直接访问函数内部的局部变量吗?
    不能, 但我们可以通过闭包让外部操作它

7.闭包的生命周期

  1. 产生: 在嵌套内部函数定义执行完时就产生了(不是在调用)
  2. 死亡: 在嵌套的内部函数成为垃圾对象
 function fn1() {
    //此时闭包就已经产生了(函数提升, 内部函数对象已经创建了)
    var a = 2
    function fn2 () {
      a++
      console.log(a)
    }
    return fn2
  }
  var f = fn1()
  f() // 3
  f() // 4
  f = null //闭包死亡(包含闭包的函数对象成为垃圾对象)

若改为下面方式定义内部函数则要整个函数执行完才产生闭包:

 function fn1() {
    
    var a = 2
    var fn2 = function  () {
      a++
      console.log(a)
    }//此时闭包产生了
    return fn2
  }
  var f = fn1()
  f() // 3
  f() // 4
  f = null //闭包死亡(包含闭包的函数对象成为垃圾对象)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值