一、什么是闭包?
先说概念:
闭包是指有权访问另一个函数作用域中变量的函数。
创建闭包的最常用的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部。
二、关于闭包概念的理解
从概念中可以看出,要形成闭包有2个不可或缺的关键因素,分别是:
①1个函数 ②函数内部可以访问的变量
比如:
var num = 665;
function sayAlert(){
alert(num);
}
(在上述例子中,num就是1个变量,而sayAlert则是一个函数,在该函数中可以访问num这个变量。)
紧接着把这几句代码放到一个立即执行函数中,再return该函数,如下所示:
function say666() {
var num = 665;
function sayAlert() {
alert(num);
}
num++;
return sayAlert;
}
var sayAlert = say666();
sayAlert(); //执行结果为弹出666
在上述例子中,sayAlert函数和num变量就形成了闭包。
可以看出有两个问题:
一、为什么需要函数嵌套函数?
函数嵌套函数是为了让变量成为局部变量,比如在上述例子中num就成为了局部变量,如果不嵌套直接写在外面就成为了全局变量。
所以,函数套函数就是为了制造出一个局部变量。
二、为什么需要return函数?
return函数就是为了让这个函数可以被使用,在上述例子中return sayAlert就是为了让这个函数在外部可以被使用。
解决了上述两个问题后,又有一个问题出现了:
为什么要让变量成为局部变量呢?
我想这个问题有好几个答案,首先是局部变量可以一直被保存在内存中,不会被垃圾回收机制回收。还有就是可以通过闭包来隐藏一个变量,比如在上述例子中我们也完全可以让num成为一个全局变量,但是我又不想让num这个变量的值被任何人任意更改(不想让别人直接访问到这个变量),所以我们可以让它成为局部变量,并且暴露一个函数,让他人可以间接访问。
三、分享一个闭包使用案例
最后给大家分享一个闭包的使用案例,使用闭包让 4个li节点的onclick事件都能正确的弹出当前被点击的li索引:
<ul>
<li>index =0</li>
<li>index =1</li>
<li>index =2</li>
<li>index =3</li>
</ul>
<script>
var nodes=document.getElementsByTagName("li");
for(var i=0;i<nodes.length;i++){
nodes[i].οnclick=(function(i){
return function(){
console.log(i)
}
})(i)
}
</script>
在上述例子中,return后的函数和变量i就形成了闭包,如果不使用闭包直接打印的话,那么不管点击哪个li打印出来的值都是4。
大家可以自行尝试。
有任何问题欢迎在留言区指出和讨论(✿◕‿◕✿)