JavaScript闭包

网友投稿 262 2022-09-06

JavaScript闭包

文章目录

​​引入​​​​什么是闭包​​​​常见的闭包​​​​闭包的作用​​​​闭包的生命周期​​

引入

思路:遍历+ 监听

var btns = document.getElementsByTagName('button') for (var i = 0,length=btns.length; i < length; i++) { var btn = btns[i] btn.onclick = function () { alert('第'+(i+1)+'个') } }

如果写成for (var i = 0; i < btns.length; i++),那么在每次循环的时候都会计算一遍btn.length会影响代码效率

我们可以使用添加属性的办法,去记录他的下标:

for (var i = 0,length=btns.length; i < length; i++) { var btn = btns[i] //将btn所对应的下标保存在btn上 btn.index = i btn.onclick = function () { alert('第'+(this.index+1)+'个') }

我们也可以用闭包的原理来做:

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

什么是闭包

首先我们来看一段代码:

function fn1 () { var a = 2 var b = 'abc' function fn2 () { //执行函数定义就会产生闭包(不用调用内部函数) console.log(a) } } fn1()

如何产生闭包?

当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量(函数)时, 就产生了闭包

闭包到底是什么?

使用chrome调试查看理解一: 闭包是嵌套的内部函数理解二: 包含被引用变量(函数)的对象注意: 闭包存在于嵌套的内部函数中

产生闭包的条件?

函数嵌套内部函数引用了外部函数的数据(变量/函数)调用了外部函数

理解一就是把红色部分当作闭包

理解二就是把绿色部分当作闭包(Closure就是闭包的意思)

常见的闭包

常见的闭包有两种情景:

将函数作为另一个函数的返回值将函数作为实参传递给另一个函数调用

①将函数作为另一个函数的返回值

// 1. 将函数作为另一个函数的返回值 function fn1() { var a = 2 function fn2() { a++ console.log(a) } return fn2 } var f = fn1() f() // 3 f() // 4

注意:

②将函数作为实参传递给另一个函数调用

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

注意:

msg是被引用对象,也就是说msg是闭包,而time不是因为内部的嵌套函数时function{}那个括号里的,而time不在里面

闭包的作用

闭包的两大作用:

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

我们可以分析以下代码:

function fn1() { var a = 2 function fn2() { a++ console.log(a) // return a } function fn3() { a-- console.log(a) } return fn3 } var f = fn1() f() // 1 f() // 0

问题二:在函数外部能直接访问函数内部的局部变量吗? 答:不能, 但我们可以通过闭包让外部操作它

闭包的作用有点类似于java中的对象的封装性。你可以将fn1当作类,将a、fn2、fn3当作对象的属性和方法。只不过这里是通过return来暴露内部方法,而java是通过权限修饰符来进行暴露。

闭包的生命周期

产生: 在嵌套内部函数定义执行完时就产生了(不是在调用)死亡: 在嵌套的内部函数成为垃圾对象时

例如以下代码:

function fn1() { //此时闭包就已经产生了(函数提升, 内部函数对象已经创建了) var a = 2 function fn2 () { a++ console.log(a) } return fn2 } var f = fn1() f() // 3 f() // 4 f = null //闭包死亡(包含闭包的函数对象成为垃圾对象)

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:科技狐:终于,华为 P50 发布时间定了!鸿蒙+高通芯!
下一篇:JavaScript闭包的应用以及缺点
相关文章

 发表评论

暂时没有评论,来抢沙发吧~