什么是 闭包
--- 1-种说法经典的场景 把一个函数作为返回值
--闭包就是一个函数
-- 2-种 -函数与其周围的状态的组合
写法 :
1. 函数嵌套函数:闭包必须有函数嵌套函数的结构。
2. 内部函数可以访问外部函数的变量:内部函数可以访问外部函数中的变量,即使在外部函数执行完毕后,这些变量仍然可以被访问。
3. 外部函数返回内部函数:外部函数必须返回内部函数,才能形成闭包。
好处:
1- 局部变量常驻内存,像是全局变量一样,常驻内存,不会污染全局命名空间
2- 产生 私有变量
闭包的原理:1-垃圾回收机制--被外部引用的局部变量没有被回收
2-作用域链 - 内部函数 使用变量的时候,会先在自身作用中,找不到就去 父级作用域中-依次类推
缺点:
容易造成内存泄露--
解决:不用的话手动赋值为null
// 变量a 和 return 的函数 就是一个闭包
function box() {
var a = 1;
return function () {
console.log(a);
a++;
return a;
}
}
let a = 1;
// let a = 1;
//调用box 以后 返回了 内部函数
let resFN = box();
console.log(resFN);
// 外部 可以使用到 一个函数 内部 局部的函数和局部的变量
// 局部变量为什么没有被回收,全局变量resFn 引用内部的函数,内部函数引用了 局部变量a
// 导致局部变量a没有被回收
/*
调用resFN 第一次,让打印了a 1, 又a++,成了2 ,返回了2
*/
let r1 = resFN();
console.log(r1);
/*
调用resFN 第二次,让打印了a 2, 又a++,成了3 ,返回了3
*/
let r2 = resFN();
console.log(r2);
resFN = null;
// 全局变量--什么时候都能使用
let num = 1;
function fn() {
// 局部变量--函数执行期间是可以用的
// 一般情况下,函数执行完毕以后, 函数的执行空间(词法环境)和局部变量 就会被销毁
// 浏览器--垃圾回收机制--内存的回收机制的算法
// 1-古老的算法--引用计数法--
// 2- 现代的算法--标记清除法----能被全局引用的 都不会被回收
let num2 = 200;
console.log(num2);
}
fn();
// console.log(num2);
下面是一个经典闭包
function fn() {
let a = 1;
return function () {
a++;
return a;
};
}
let newFn = fn();
console.log(newFn());
console.log(newFn());
console.log(newFn());
console.log(newFn());
console.log(newFn());
可以看到得到结果为 2,3,4,5,6,