JavaScript中闭包的简单介绍
一、闭包的基本概念
1、闭包是函数的一种高级应用方式,通过建立一个不被销毁的存储空间,来在函数的外部调用和使用函数内部的数据。简单来说,闭包实际上就是一个函数,只不过是处于其他函数内部而已。
2、由于在 JavaScript 中,只有函数内部的子函数才能读取其中的局部变量,所以说,闭包就可以简单理解成“定义在一个函数内部的函数“。
3、所以,从在本质上来看,闭包就是将函数内部和函数外部连接起来的桥梁。
二、定义闭包的本质
(三个条件缺一不可)
1、定义一个函数a,返回值是一个函数b;
2、在返回值函数b中,使用函数a定义的局部作用域变量;
3、在函数a的外部,引用函数a,并且执行返回值函数b
1 定义一个函数A
function funA(){
let a = 100;
let b = 200;
返回值是一个函数B
return function funB(){
2 在函数B中,引用了函数A中定义的局部作用域变量
let abc = {num1:a,num2:b};
返回值是 abc 也就是,函数a中的局部作用域变量
return abc;
}
}
3 在函数a外部,调用引用函数A
此时变量a1 中, 存储的是 函数B的内存地址
let a1 = funA();
调用a1,实际就是通过a1中存储的函数B的内存地址,来调用函数B
此时a2存储的应该是函数B的返回值 abc ,也就是 函数A中的局部作用域变量
let a2 = a1();
console.log(a2);
三、产生的历史背景
1、在JavaScript大环境下遵循以下规则:
函数内部可以读取函数外部的全局变量;在函数外部无法读取函数内的局部变量。
2、使用闭包的原因:
因为在 JS 中变量的作用域分为全局变量和局部变量。在函数外部无法读取函数内的局部变量,这就需要闭包来解决。
3、解决的问题:
实现了在函数外部可以读取函数内的局部变量,就出现了闭包。让函数执行完成后,内部的函数、变量还能被调用,可以采用闭包延长局部变量或函数的生命周期。
四、闭包的特点
既是优点,也是缺点
1、函数作用域空间不会被销毁
优点:空间中的内容,永远存在
缺点:占用大量的内存空间
2、可以从外部访问函数内部的变量
优点:使用变量数据方便
缺点:容易泄露数据信息
3、保护私有作用域变量
优点:确保私有作用域变量一直存在
缺点:外界无法访问函数中的变量
4、闭包的最大问题
有可能会造成占用大量的内存空间, 降低程序的执行效率,甚至有可能造成数据溢出或者是数据泄露。 因此,为了保护数据的安全性,特殊情况下才会使用闭包。
五、闭包的实际应用的小案例
设计:点击每一个li标签,控制台输出对应的li内容
<style>
ul,li{list-style: none;}
</style>
<ul>
<li>第一个li标签</li>
<li>第二个li标签</li>
<li>第三个li标签</li>
<li>第四个li标签</li>
<li>第五个li标签</li>
</ul>
<script>
let oLis = document.querySelectorAll('li');
使用 闭包 的方式执行(用到自执行函数)
1 定义一个for循环
通过生成所有的索引,来循环遍历oLis中的所有标签对象
for(var i = 0 ; i <= oLis.length-1 ; i++){
2 给li绑定点击事件,需要立即执行,获取i的数值
绑定事件的第二个参数就是个自执行函数
oLis[i].addEventListener('click',(function(int){
3 返回值是个函数(符合 闭包 规则)
return function(){
console.log(int+1)
}
}) (i) )
}
</script>
最终实现后的效果如下: