闭包又称函数闭包或者词法闭包,是在支持函数是一等公民的编程语言中出现的一种结构体,它存储了一个函数和一个关联的环境,当捕捉闭包的时候,它的自由变量会在捕捉的时候被确定,这样即使脱离了捕捉上下文,它也能照常运行。每创建一个函数,闭包就会在函数被创建出来的时候同时被创建。
/**
* 闭包是一个函数以其捆绑的周边环境状态的引用的组合。闭包让开发者可以从内部函数访问外部函数的作用域
* 闭包会随着函数的创建而同时被创建
*/
//来自mdn的一个例子
function makeAdder(x) {
return function (y) {
return x + y;
}
}
var add5 = makeAdder(5);//这个函数的x=5变量都不会被销毁
var add10 = makeAdder(10);//这个函数x=10变量不会被销毁
//来自vue3源码工具函数
const cacheStringFunction = (fn) => {
const cache = Object.create(null);//这里的cache就可以缓存所有函数以及函数的处理结果
return (str) => {
const hit = cache[str];
return hit || (cache[str] = fn(str));
}
}
const capitalize = cacheStringFunction((str) => {
str.charAt(0).toUpperCase();
})
//用函数模拟私有变量
const Count = (() => {
let a = 10;
const changeA = (arg) => {
a = arg;
}
return {
increment: () => {
a++;
changeA(a);
},
decrement: () => {
a--;
changeA(a);
},
value: () => {
return a;
}
}
})()
console.log(Count.value());
Count.increment();
Count.increment();
console.log(Count.value());
闭包会造成上层函数作用域在函数执行完毕后不释放的问题,所以大量闭包的使用会造成内存泄漏。所以当不使用闭包时,应该手动去释放内存
var n = 999;
function f1(){
var n = 1000;
function f2(){
console.log(n);
}
return f2
}
function f3(p){
var n = 1001;
p();
}
f3(f1());
/**
* 首先分析f1的执行
* f1执行时会返回f2,在f2中访问了n,所以n也会被返回出来,里边通过var定义了一个n则不会访问var n=999;
* 执行f3,此时执行p,但是闭包是在函数定义时生成的所以n不会是1001;而是1000
*/