JavaScript:闭包

在说JavaScript中闭包概念之前,我们先来了解一下作用域和变量生命周期的问题。作用域在前面的博客中有提到,大家可以点击查看一下,关于变量的生命周期,什么是生命周期?也就是变量从创建到销毁的一个过程。对于全局变量,它的生命周期是永久的,除非我们在开发中主动销毁这个变量,而在函数中的局部变量,当退出该函数时,这个函数内的局部变量回随着函数的结束而被销毁。了解了作用域和生命周期的基本概念后,我们来说一下闭包。

什么是闭包?闭包就是指有权限访问另一个函数作用域内变量的函数,通常情况下就是一个函数中包含另一个函数。我们先来看一个有关闭包特点的经典案例,代码如下:

<div>0</div>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<script>
    var divList = document.getElementsByTagName('div');
    for (let index = 0; index < divList.length; index++) {
        divList[index].onclick = function(){
            console.log(i);
        }
    }
</script>

点击不同的div,获取对应的text,上面代码的实现结果却不随人愿,你会发现点击任意div,都是打印的5,问题来了:为啥打印的都是5呢?原因很简单,因为点击的onclick事件是异步触发的,当点击事件被触发时,for循环早已结束,此时变量i的值早已经是5,所以不管你点击哪一个,都会打印的是5。如何解决呢?这时候就可以用到闭包了,请看如下代码:

var divList = document.getElementsByTagName('div');
for (let index = 0; index < divList.length; index++) {
    divList[index].onclick = (function (i) {
        return function(){
            console.log(i);
        }
    })(index)
}

上面的第二种方式,就是借助了闭包的特点,在for循环的时候,每次循环将index值封闭起来,当点击事件触发的时候,就会顺着当前的作用域链由内往外依次寻找变脸index,这时就会找到被封闭在闭包环境内的index值,这样点击对应的div时就会打印对应的text。

看到上面的例子,我们可以看出创建闭包的常见方式,就是在一个函数的内部再创建另一个函数,通过另一个函数访问这个局部变量,利用闭包的特性就可以突破作用域链的限制,就可以将函数内部的变量和方法暴露到外部,这样外部就可以访问函数内部的变量和方法,闭包实现的原理就是:

  • 闭包自身的作用域链包含着自己的作用域,函数作用域以及全局作用域;
  • 函数作用域和函数内的局部变量,会在函数执行后销毁;
  • 当函数返回的是一个闭包时,这个函数的作用域会一直在内存中保存;

闭包的特点:

  • 可以访问函数内部的变量和方法,保持函数在代码环境内一直存在,不会被垃圾回收机制处理;
  • 函数内再嵌套函数,子级向父级查找变量,逐级查找;

闭包的缺点:

  • 上面说到的原理中,闭包自身的作用域链包含着自己的作用域,函数作用域以及全局作用域,这也是它的缺点,由于它的这个特点,我们就需要去维护一些额外的作用域;
  • 由于不会被垃圾回收机制处理,所以如果大量使用闭包的话,就会占用过多的内存;
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值