什么是闭包
闭包就是内部函数。何为内部函数呢?即是可以通过在一个函数内部或者块级作用域里面定义的函数。
(function autorun(){
let x = 1;
function log(){
console.log(x);
}
log();
})();
复制代码
此时,log() 函数就是一个闭包。
闭包特性
- 内部函数可以访问外部函数定义的变量。即使外部函数已经执行完毕。
- 闭包只存储外部变量的引用。
- 作用域是定义时的作用域,而不是执行时的作用域。即是词法作用域
闭包作用
适用场景:
- 当外部函数执行完,内部函数依然存活。例如异步操作。
- 函数当作返回值。
- 定时器、事件监听器、Ajax请求、跨窗口通信、Web Workers或者任何其他的异步(或者同步)任务中,只要使用了回调函数,实际上都是在使用闭包。
闭包缺点
- 多个子函数的[[scope]]都是同时指向父级,是完全共享的。因此当父级的变量对象被修改时,所有子函数都受到影响。
解决办法:
- 变量可以通过 函数参数的形式 传入,避免使用默认的[[scope]]向上查找
- 使用setTimeout包裹,通过第三个参数传入
- 使用 块级作用域,让变量成为自己上下文的属性,避免共享
- 内存泄漏