JavaScript 闭包应用场景详解

JavaScript 闭包应用场景详解

闭包是JavaScript中一个强大且重要的概念,它指的是函数与其词法环境的组合,允许函数访问并记住其定义时的作用域。下面我将通过具体示例展示闭包的四个主要应用场景:

应用场景及示例

1. 封装私有变量(防抖/节流)

javascript 复制代码
// 防抖函数(私有变量:timer)
function debounce(fn, delay) {
  let timer = null; // 闭包保存的私有变量
  return function() {
    clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, arguments);
    }, delay);
  };
}

// 节流函数(私有变量:lastTime)
function throttle(fn, interval) {
  let lastTime = 0; // 闭包保存的私有变量
  return function() {
    const now = Date.now();
    if (now - lastTime >= interval) {
      fn.apply(this, arguments);
      lastTime = now;
    }
  };
}

// 使用示例
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', debounce(function() {
  console.log('搜索:', this.value);
}, 300));

window.addEventListener('scroll', throttle(function() {
  console.log('滚动位置:', window.scrollY);
}, 200));

2. 实现单例模式

javascript 复制代码
const Singleton = (function() {
  let instance = null; // 闭包保存唯一实例
  
  function createInstance() {
    return {
      id: Math.random().toString(36).substr(2, 9),
      createdAt: new Date()
    };
  }
  
  return {
    getInstance: function() {
      if (!instance) {
        instance = createInstance();
      }
      return instance;
    }
  };
})();

// 使用示例
const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // true
console.log('实例ID:', instance1.id);

3. 柯里化函数

javascript 复制代码
// 柯里化函数
function curry(fn) {
  const arity = fn.length;
  
  return function curried(...args) {
    if (args.length >= arity) {
      return fn.apply(this, args);
    } else {
      return function(...moreArgs) {
        return curried.apply(this, args.concat(moreArgs));
      };
    }
  };
}

// 使用示例
const multiply = (a, b, c) => a * b * c;
const curriedMultiply = curry(multiply);

console.log('结果1:', curriedMultiply(2)(3)(4)); // 24
console.log('结果2:', curriedMultiply(2, 3)(4)); // 24
console.log('结果3:', curriedMultiply(2)(3, 4)); // 24

4. 缓存计算结果(记忆函数)

javascript 复制代码
// 记忆函数
function memoize(fn) {
  const cache = {}; // 闭包保存计算结果缓存
  
  return function(...args) {
    const key = JSON.stringify(args);
    if (cache[key] !== undefined) {
      console.log('从缓存获取结果');
      return cache[key];
    }
    
    console.log('执行计算');
    const result = fn.apply(this, args);
    cache[key] = result;
    return result;
  };
}

// 使用示例
function fibonacci(n) {
  if (n <= 1) return n;
  return fibonacciMemo(n - 1) + fibonacciMemo(n - 2);
}

const fibonacciMemo = memoize(fibonacci);

console.log('fib(10):', fibonacciMemo(10)); // 计算10次
console.log('fib(10):', fibonacciMemo(10)); // 从缓存获取
console.log('fib(11):', fibonacciMemo(11)); // 只计算1次(利用缓存结果)

闭包原理说明

闭包的核心原理是函数可以记住并访问其词法作用域,即使函数在其词法作用域之外执行。这种机制使得函数可以:

  1. 访问定义时的作用域变量
  2. 维护私有状态
  3. 封装数据和功能
  4. 创建模块化的代码结构
graph TD A[外部函数] --> B[定义内部函数] B --> C[内部函数引用外部变量] A --> D[返回内部函数] D --> E[外部函数执行结束] E --> F[内部函数仍可访问外部变量]

闭包应用总结表

应用场景 闭包作用 示例说明 关键优势
封装私有变量 保存状态 防抖/节流中的定时器变量 避免全局污染,保护数据
单例模式 保存唯一实例 只创建一个全局共享实例 节省资源,控制访问
柯里化函数 保存部分参数 分步传递参数,延迟执行 函数组合,代码复用
缓存计算结果 保存计算结果缓存 记忆函数避免重复计算 提高性能,优化计算

闭包是JavaScript编程中的强大工具,理解并掌握它可以显著提高代码质量和开发效率。

相关推荐
IT_陈寒33 分钟前
Vite动态导入把我坑惨了,原来要这样用才对
前端·人工智能·后端
DFT计算杂谈37 分钟前
KPROJ编译教程
java·前端·python·算法·conda
觅_40 分钟前
前端学习后端的时候 选择一个技术
前端·学习
独泪了无痕42 分钟前
CryptoJS:数据安全的JavaScript加密利器
前端·vue.js·node.js
发现一只大呆瓜1 小时前
一文搞懂 Vite 处理CommonJS包、按需编译逻辑及 Rollup 插件兼容规则
前端
Edwardwu1 小时前
写了个y-mxgraph:给 draw.io 接上了 Yjs,顺便解决了部署在 iframe 里的一堆问题
前端·typescript
其实防守也摸鱼1 小时前
软件安全与漏洞--软件安全编码
java·前端·网络·安全·网络安全·web·工具
发现一只大呆瓜2 小时前
Vite 开发预构建机制详解,搞懂 esbuild 与 Rollup 分工差异
前端·面试·vite
九九落3 小时前
前端获取经纬度完全指南:从Geolocation API到地图集成
前端·获取经纬度
来恩10033 小时前
jQuery选择器
前端·javascript·jquery