闭包
闭包是什么?
- 定义: 引用了其他函数作用域中变量的函数;
- 形成条件: 内层函数被外层函数返回或传出, 并引用了外层的标识符;
const addTo = (x) => (y) => x + y;
const addToFive = addTo(5);
addToFive(3); // 8
闭包为什么会让外部函数的变量不被销毁?
- 常规流程: 函数执行完毕后其变量对象被销毁, 只保留全局对象;
- 闭包行为: 闭包把自己的外层变量对象加入作用域链, 从而延长其生命周期;
- 释放方式: 只要闭包本身仍被引用, 外层变量对象就无法回收, 需要时手动置空引用;
let compareNames = createComparisonFunction("name"); // 外层变量对象被保留
compareNames = null; // 解除引用后才能回收
闭包中如何访问外层函数的 this?
- 限制: 内部普通函数不能直接继承外层函数的 this, 它在调用时重新绑定;
- 办法: 在外层把 this 存入闭包可访问的变量;
window.identity = "The Window";
const object = {
identity: "My Object",
getIdentityFunc() {
const that = this;
return function () {
return that.identity;
};
},
};
object.getIdentityFunc()(); // "My Object"
- 更简单的替代: 内层改用箭头函数, 直接沿用外层 this, 见 this 绑定;
闭包适合用在哪些场景?
- 状态保持: 防抖节流、定时器与各种回调中保存上下文;
- 封装: 实现私有变量与方法、模块化与 IIFE;
- 生成器: 函数工厂与缓存函数结果;