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闭包。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程