- 概念
闭包函数: 声明在一个函数中的函数,叫做闭包函数。
闭包: 内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回了之后。
- 闭包的应用场景
- 创建独立的模块,封装私有变量和方法,避免全局污染
- 回调函数
- 高阶函数,如防抖和节流
- 函数工厂,动态生成函数
。。。。。。
- 闭包的创建
闭包就是可以创建一个独立的环境,每个闭包里面的环境都是独立的,互不干扰。闭包会发生内存泄漏,每次外部函数执行的时候,都会开辟一块内存空间,外部函数的引用地址不同,都会重新创建一个新的地址
结论: 闭包找到的是同一地址中父级函数中对应变量最终的值
例子一:
function outerFn(){
var i = 0;
function innerFn(){
i++;
console.log(i);
}
return innerFn;
}
var inner = outerFn(); //每次外部函数执行的时候,都会开辟一块内存空间,外部函数的地址不同,都会重新创建一个新的地址
inner();
inner();
inner();
var inner2 = outerFn();
inner2();
inner2();
inner2(); //1 2 3 1 2 3
例子二:
for (var i = 0; i < 10; i++) {
const task = () => new Promise(resolve => {
// 这里 i 的值是以前非常高频的闭包题
setTimeout(() => {
console.log(`task${i} complete`);
resolve(`task${i}`);
}, 2000);
});
task();
}
// 输出
task10 complete
task10 complete
task10 complete
task10 complete
task10 complete
task10 complete
task10 complete
task10 complete
task10 complete
task10 complete
例子三:
for (let i = 0; i < 10; i++) {
const task = () => new Promise(resolve => {
// 这里 i 的值是以前非常高频的闭包题
setTimeout(() => {
console.log(`task${i} complete`);
resolve(`task${i}`);
}, 2000);
});
task();
}
// 输出
task0 complete
task1 complete
task2 complete
task3 complete
task4 complete
task5 complete
task6 complete
task7 complete
task8 complete
task9 complete
例子四:
for (var i = 0; i < 10; i++) {
(function(i) { // 立即执行函数创建独立作用域
const task = () => new Promise(resolve => {
setTimeout(() => {
console.log(`task${i} complete`); // 捕获 IIFE 内部的 i
resolve(`task${i}`);
}, 2000);
});
task();
})(i); // 传入当前迭代的 i 值
}
例子五:
function outerFn(){
var i = 0;
function innerFn(){
i++;
console.log(i);
}
return innerFn;
}
var inner = outerFn(); //每次外部函数执行的时候,都会开辟一块内存空间,外部函数的地址不同,都会重新创建一个新的地址
inner();
inner();
inner();
var inner2 = outerFn();
inner2();
inner2();
inner2(); //1 2 3 1 2 3
var fn=(function(){
var i=10;
function fn(){
console.log(++i);
}
return fn;
})()
fn(); //11
fn(); //12
一些碎碎念~