JavaScript 中的函数闭包有多种用法,以下是一些常见的用法:

1. 封装私有变量和方法:

/* 使用自执行函数+闭包实现私有变量的创建 */
(function f(){
let str='私有变量'
function ff(){
  console.log(str);  
}
ff()
})()

通过定义了一个立即执行的匿名函数,在创建私有变量 str 后,通过内部函数 ff 形成的闭包来访问并输出该变量的值,然后立即执行完成整个操作过程,使得str不被外界访问,具有“私有性质”。

2. 实现模块化和命名空间:闭包可以用于创建模块,将相关的变量和方法组织在一个独立的词法环境中,避免全局命名冲突。

const Calculator = (function() {
  // 私有变量
  let history = [];
  
  // 私有方法
  function addToHistory(operation, result) {
    history.push({ operation, result, timestamp: new Date() });
  }
  
  // 公共接口
  return {
    add: function(a, b) {
      let result = a + b;
      addToHistory(`add(${a}, ${b})`, result);
      return result;
    },
    
    subtract: function(a, b) {
      let result = a - b;
      addToHistory(`subtract(${a}, ${b})`, result);
      return result;
    },
    
    getHistory: function() {
      return history.slice(); // 返回副本,保护原始数据
    },
    
    clearHistory: function() {
      history.length = 0;
    },
    
    getHistoryCount: function() {
      return history.length;
    }
  };
})();

// 使用
console.log(Calculator.add(5, 3)); // 8
console.log(Calculator.subtract(10, 4)); // 6
console.log(Calculator.getHistory()); // 查看历史记录
console.log(Calculator.getHistoryCount()); // 2

我们通过使用立即执行函数表达式(IIFE)创建了一个Calculator计算器模块,通过闭包机制将history历史记录数组和addToHistory方法封装为私有成员,同时对外暴露了add、subtract、getHistory等公共方法,既实现了功能的模块化组织,又保护了内部数据不被外部直接访问,有效避免了全局命名空间的污染。

闭包有利也有弊,下面我们通过表格来看看JS中闭包有哪些利弊:

优点缺点
数据封装和私有化内存占用增加
状态持久化保持内存泄漏风险(只针对IE浏览器)
模块化和命名空间性能开销较大
避免全局变量污染调试追踪困难
实现回调函数机制代码复杂度提高
创建函数工厂循环引用问题

总结:有效利用闭包特性能够实现私有变量的存储,但是闭包容易内存泄漏,具有代码逻辑复杂等特点,读者需要审慎使用,合理运用JS闭包。

点赞(197)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)