闭包
一、什么是闭包?
闭包指的是,在一个函数内部有一个子函数,这个子函数和父函数之间存在变量引用关系,那么这个变量就不会被垃圾回收机制自动回收,会把这个变量的最终状态缓存起来,常驻在内存中。
二、闭包的优点
- 可以在函数外部读取到函数内部的变量
- 让这些变量始终保持在内存中,不会在外层函数调用后被自动清除
- 用于封装函数功能,避免了全局变量的污染
三、闭包的缺点
- 变量会常驻内存中,增大内存的使用,使用不当时容易造成内存泄漏
- 闭包会在父函数外部,改变父函数内部变量的值,可能会导致函数内部错乱
- 使用闭包时要小心,因为不会自动释放,所以会增加内存开销
四、闭包的用途
在想实现某种效果,而不愿意使用全局变量或者给函数增加一个额外的参数的时候,可以考虑使用闭包
五、闭包示例
// 没有使用闭包
function add(a=0) {
a += 1;
console.log(a);
}
add(); // 1
add(); // 1
add(); // 1
// 使用闭包
function add(a=0) {
function fn() {
a += 1;
console.log(a);
}
return fn;
}
var fn = add();
fn(); // 1
fn(); // 2
fn(); // 3
接下来使用闭包完成推平(展平)数组的示例
// 推平数组
function flat(data) {
// 缓存推平数组的数组变量
var newArr = [];
// 立即执行函数,引用父函数的变量,形成了闭包,变量会被缓存在内存中
+function loop(arr) {
// 利用数组forEach方法遍历数组
arr.forEach((item) => {
// 如果当前数据是数组,则递归子函数loop
if (Array.isArray(item)) {
loop(item);
} else { // 如果当前数据不是数组,则直接push到父函数的变量newArr中
newArr.push(item);
}
})
}(data);
return newArr;
}
var data = [1, 2, 3, [4, 5, 6, [7, 8, 9]], 10];
console.log(flat(data));