闭包
闭包,字面上理解就是一个闭合的容器。在浏览器查看时,闭包是一个对象 closure {key:value};
- 闭包的条件
- 函数的
嵌套
- 内部函数
使用外部函数
的局部变量 - 外部函数调用(这个是肯定的。因为只有调用了,才有了上下文环境,代码才会执行。)
- 函数的
- 缺点
- 占内存。因为闭包使用了外部函数的局部变量,而外部函数在调用完,按理说会出栈。但由于闭包的存在,所以会延迟外部的局部变量的生命周期。
- 不及时清除闭包会导致内存溢出(因为占内存,闭包多了,内存自然就不够了)
- 如何避免其缺点
- 能不用就不用
- 及时清除。使其
为null
.
- 使用场景
- 解决循环遍历时,事件监听的问题。
- 将内部的函数return出来
- 将函数作为实参传递给另一个函数调用。
function f() {
var num = 0;
function f1() {
num = num + 1;
return num;
}
return f1;
}
var a = f();
const c1 = a();
const c2 = a();
const c3 = a();
console.log(c1, c2, c3); // 1,2,3
上面的例子解释了: 返回的函数可以访问不属于全局作用域的变量,但它们仅存在于其闭包中。
function fun(n, o) {
console.log(o);
return {
fun: function(m) {
return fun(m, n);
}
}
}
var a = fun(0);
a.fun(1);
a.fun(2);
a.fun(3);
//undefined 0 0 0
var b = fun(0).fun(1).fun(2).fun(3); //undefined 0 1 2
var c = fun(0).fun(1);
c.fun(2);
c.fun(3);
//undefined 0 1 1
闭包的方法是通过类比 "背包" 。当一个函数被创建并传递或从另一个函数返回时,它会携带一个背包。背包中是函数声明时作用域内的所有变量。
这里还是不行。对于闭包,结合setTimeout()的异步。闭包会更加复杂。但目前异步还不太理解。