前端闭包的5大实际应用场景

7 阅读1分钟

前端闭包的5大实际应用场景(附面试加分示例)

一、模块化封装(隔离作用域)

核心场景:避免全局变量污染,实现私有变量和方法的封装。

示例:封装工具函数库(如防抖节流、工具类):

const utils = (() => {
​
    // 私有变量(外部无法直接访问)
​
    const privateKey = "xxx";
​
    return {
​
      getEncrypted: (data) => {
​
        // 利用闭包访问privateKey
​
        return encrypt(data, privateKey);
​
      },
​
      formatTime: (time) => format(time) // 暴露公共方法
​
    };
​
})();
​
utils.getEncrypted("test"); // 可访问
​
utils.privateKey; // undefined(无法访问私有变量)

面试加分:提及 “IIFE(立即执行函数)+ 闭包” 是 ES6 模块普及前的核心模块化方案。

二、状态维持(保留变量上下文)

核心场景:需要持续追踪状态的功能(计数器、表单状态、缓存)。

示例 1:计数器

function createCounter() {
​
    let count = 0; // 闭包保留count状态
​
    return {
​
      increment: () => count++,
​
      getCount: () => count
​
    };
​
}
​
const counter = createCounter();
​
counter.increment(); // 1
​
counter.increment(); // 2(状态持续保留)

示例 2:请求缓存

function createRequestCache() {
​
    const cache = {}; // 闭包缓存请求结果
​
    return async (url) => {
​
      if (cache[url]) return cache[url];
​
      const res = await fetch(url);
​
      cache[url] = res.json();
​
      return cache[url];
​
    };
​
}
​
const request = createRequestCache();
​
request("/api/data"); // 首次请求,缓存结果
​
request("/api/data"); // 直接返回缓存(避免重复请求)

三、防抖与节流函数(面试高频)

核心场景:限制高频事件触发(滚动、输入、点击),优化性能。

示例:防抖函数(输入框搜索联想)

function debounce(fn, delay) {
​
    let timer = null; // 闭包保存定时器ID
​
    return (...args) => {
​
      clearTimeout(timer); // 清除上一次定时器
​
      timer = setTimeout(() => fn.apply(this, args), delay);
​
    };
​
}
​
// 应用:输入框搜索(停止输入300ms后执行)const search = debounce((value) => fetch(`/api/search?key=${value}`), 300);
​
input.addEventListener("input", (e) => search(e.target.value));

四、函数柯里化(参数复用)

核心场景:将多参数函数转化为单参数函数,复用前置参数。

示例:用户权限校验

// 柯里化函数:先传入权限阈值,再传入用户权限
​
function checkPermission(requiredRole) {
​
    // 闭包保留requiredRole
​
    return (userRole) => userRole >= requiredRole;
​
}
​
// 复用:创建“管理员权限校验”和“普通用户校验”
​
const isAdmin = checkPermission(3);
​
const isNormalUser = checkPermission(1);
​
isAdmin(3); // true(管理员)isNormalUser(2); // true(普通用户)

五、React/Vue 中的闭包应用

核心场景:组件状态持久化、钩子函数中保留上下文。

示例 1:React 自定义 Hook(保留定时器)

function useInterval(callback, delay) {
​
    const savedCallback = useRef();
​
    // 闭包保存最新callback(避免依赖更新问题)
​
    useEffect(() => {
​
      savedCallback.current = callback;
​
    }, [callback]);
​
    useEffect(() => {
​
      const timer = setInterval(() => savedCallback.current(), delay);
​
      return () => clearInterval(timer); // 清除定时器
​
    }, [delay]);
​
}

示例 2:Vue 生命周期中保存数据

export default {
​
    mounted() {
​
      const initialData = this.formData; // 闭包保留初始值
​
      this.$watch("formData", (newVal) => {
​
        // 对比当前值与初始值(initialData通过闭包访问)
​
        if (JSON.stringify(newVal) !== JSON.stringify(initialData)) {
​
          this.isModified = true;
​
        }
​
      });
​
    }
​
};