1.什么是闭包?
闭包(closure)指有权访问另一个函数作用域中变量的函数。
简单理解就是,一个作用域可以访问另外一个函数内部的局部变量。
如:
<script>
function fn() {
var name = 'xy';
function fun() {
console.log(name);
}
fun();
}
fn();
</script>
这里fun函数内输出了fn函数内的name变量,则产生了闭包
2.闭包的作用
闭包的作用简单讲就是:延申了变量的作用范围
<script>
function fn() {
var name = 'xy';
return function () {
console.log(name);
}
}
var f = fn();
f();
</script>
我们还可以通过直接return function ,再在全局作用域调用,这样在全局也能得到fn局部作用域内的name属性,并且局部属性name只有在f()执行后才会销毁,显而易见,闭包延申了变量的作用范围
3.闭包案例(点击li输出当前li的索引)
如果我们这样写
<li></li>
<li></li>
<li></li>
<script>
var lis = document.querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
lis[i].onclick = function () {
console.log(i);
}
}
</script>
点击任何li输出结果都为3
这是因为点击事件是异步执行的,此时for循环早已结束,i已经自加为3了,这时点击li当然输出为3,那如果在遍历的时候就保留了每个i的值,然后点击的时候再去拿这个值不就可以了吗。那怎么保存?只能在点击事件外保存,那怎么得到,这时闭包就能很好解决了。
<script>
var lis = document.querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
(function (i) {
lis[i].onclick = function () {
console.log(i);
}
})(i)
}
</script>
这里通过在点击函数外包裹了一层立即函数,然后将当前的i值以参数的形式存在立即函数中,然后点击函数拿到了立即函数传来的i值,这里就产生了闭包。