什么是闭包,以及在实际开发中哪些场景会用到?

4 阅读1分钟

“闭包本质上是一个函数,它能访问并记住其词法作用域,即使该函数在其词法作用域之外执行。

它的核心价值在于数据私有化状态保持

在实际开发中,我常用它来实现模块化封装(防止全局污染)、防抖节流函数、以及函数柯里化。

不过在使用时需要注意,闭包会让变量常驻内存,使用不当容易造成内存泄漏,所以在不需要的时候需要手动将引用置空。”

代码示例:

正常情况下,函数执行完,其内部变量会被销毁(垃圾回收)。
但闭包的特殊之处在于:外部函数执行完毕后,其作用域链依然被内部函数引用着,导致外部函数的变量对象(AO)无法被回收,依然保存在内存中。这就是闭包的“记忆效应”。

function outer() {
    let a = 1; // 外部函数的局部变量
    return function inner() { // 内部函数
        console.log(a); // 访问了外部函数的变量
    }
}

const fn = outer(); // outer 执行完毕,按理说 a 应该销毁
fn(); // 输出 1,a 依然存在,这就是闭包

柯里化与偏函数

这是函数式编程的基础。利用闭包预先设置一些参数,生成一个新的函数。

场景:  封装通用的请求函数。

function makeRequest(baseURL) {
    // baseURL 被闭包记住了
    return function(path, params) {
        console.log(`请求地址: ${baseURL}${path}`, params);
        // 实际发送 fetch 请求...
    }
}

const requestLocal = makeRequest('http://localhost:3000');
const requestOnline = makeRequest('https://api.production.com');

// 后续调用非常简洁
requestLocal('/user', {id: 1}); // 请求地址: http://localhost:3000/user
requestOnline('/order', {id: 2}); // 请求地址: https://api.production.com/order