1. 什么是闭包
(1)在介绍闭包之前,我们先重新认识一下函数的执行空间:
function fn(){
console.log("我是fn");
}
fn();
- 函数在执行的时候,会开辟一个执行空间(暂且叫它xxx);
- 那么上面的代码console.log(“我是fn”) 就是在xxx这个空间内执行的;
- 代码执行完毕以后,这个xxx空间就销毁了。
(2)闭包就是能够读取其他函数内部变量的函数,是JS中函数的一种高级应用。在JS中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解为”定义在一个函数内部的函数
”。
例:
function fn() {
var b = 1;
// 闭包
function box() {
console.log(b);
}
// 返回一个函数,这个函数就是一个闭包
return box;
}
// res 就是 box 函数
var res = fn();
// 2秒以后调用res函数,还是能打印b的值,闭包能让局部变量常驻内存
setTimeout(function() {
res();
}, 2000);
2. 闭包的特点
(1)可以读取函数内部的变量。
变量的作用域无非就是两种:全局变量和局部变量;
JS语言的特殊之处,就在于函数内部可以直接读取全局变量;
另一方面,函数外部自然无法读取函数内的局部变量。
(2)让这些变量的值始终保存在内存中,作用域空间不销毁,相对于局部变量来说,浪费了内存。
(3)保护私有变量。
3. 闭包的形成环境:
(1)函数的嵌套
(2)内部函数使用外部函数中的变量
(3)将内部函数返回,在外部函数的外部,接收返回值,执行(相当于执行了内部函数)
4. 闭包的应用场景
(1)函数作为返回值。
function box() {
var n = 1;
function cox() {
n++;
return n;
}
return cox;
}
// res 就是一个闭包 ,n像是一个全局变量
var res = box();
console.log(res()); // 2
console.log(res()); // 3
(2)循环中的事件,事件处理函数中使用了循环的每次的计数器。
<body>
<div id="box"></div>
<ul class="list">
<li>link1</li>
<li>link2</li>
</ul>
</body>
<script>
var ali = document.querySelectorAll(".list li");
for(var i=0;i<ali.length;i++){
ali[index].onclick = (function(index){
return function(){
console.log(index);
}
})(i);
}
</script>
(3)给某些系统默认的回调函数,传参。
function fn(a){
return function(){
console.log(a);
};
}
setTimeout(fn("world"), 1000);
(4)处理掉全局变量。
var f = (function(){
var a = "hello";
function fn(){
console.log(a + "world");
}
return fn;
})();
f();