当然可以!以下是从入门到精通的 JavaScript 闭包练习项目,适合不同阶段的学习者。这些项目不仅帮助你掌握闭包的概念,还能提升你在实际开发中使用闭包的能力。
🌱 初级(入门):理解基本概念和用法
✅ 练习1:计数器函数
目标:创建一个返回递增计数器的函数。
javascript
function createCounter() {
let count = 0;
return function() {
return ++count;
}
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2💡 学习点:闭包保留外部作用域变量
✅ 练习2:带初始值的计数器工厂
目标:允许传入初始值和步长。
javascript
function createCounterFactory(start, step) {
let count = start || 0;
const stepVal = step || 1;
return function() {
count += stepVal;
return count;
}
}💡 学习点:参数传递 + 闭包封装状态
✅ 练习3:私有变量封装
目标:模拟类的私有属性。
javascript
function Person(name) {
let _name = name;
this.getName = function() {
return _name;
};
this.setName = function(newName) {
_name = newName;
};
}💡 学习点:闭包实现信息隐藏
🌿 中级(进阶):结合实际场景应用
✅ 练习4:节流函数(throttle)
目标:限制高频函数调用频率,例如滚动或窗口调整事件。
javascript
function throttle(fn, delay) {
let lastCall = 0;
return function(...args) {
const now = Date.now();
if (now - lastCall >= delay) {
fn.apply(this, args);
lastCall = now;
}
}
}💡 应用场景:性能优化、防抖动
✅ 练习5:记忆化函数(memoization)
目标:缓存函数计算结果,避免重复计算。
javascript
function memoize(fn) {
const cache = {};
return function(...args) {
const key = JSON.stringify(args);
return key in cache ? cache[key] : (cache[key] = fn.apply(this, args));
}
}
// 示例:斐波那契数列优化
const fib = memoize(n => n <= 1 ? n : fib(n - 1) + fib(n - 2));
console.log(fib(10)); // 55💡 学习点:闭包 + 性能优化技巧
✅ 练习6:模块模式(Module Pattern)
目标:使用闭包实现模块化结构,暴露公共方法。
javascript
const CounterModule = (function () {
let count = 0;
function increment() {
count++;
}
function getCount() {
return count;
}
return {
increment,
getCount
};
})();
CounterModule.increment();
console.log(CounterModule.getCount()); // 1💡 学习点:模块化编程 + 私有状态管理
🌲 高级(精通):深入闭包与工程实践
✅ 练习7:异步任务队列调度器
目标:使用闭包封装异步任务的状态和执行逻辑。
javascript
function createTaskQueue() {
let tasks = [];
let isRunning = false;
function runNext() {
if (tasks.length === 0) return;
isRunning = true;
const task = tasks.shift();
task().then(() => {
isRunning = false;
runNext();
});
}
return {
add(task) {
tasks.push(task);
if (!isRunning) runNext();
}
};
}
// 使用示例
const queue = createTaskQueue();
queue.add(() => new Promise(resolve => setTimeout(() => {
console.log("Task 1 done");
resolve();
}, 1000)));
queue.add(() => new Promise(resolve => setTimeout(() => {
console.log("Task 2 done");
resolve();
}, 500)));💡 学习点:异步控制流 + 状态封装
✅ 练习8:构建简单的观察者/发布订阅系统
目标:使用闭包管理事件监听器列表。
javascript
function createEventEmitter() {
const listeners = [];
return {
on(listener) {
listeners.push(listener);
},
emit(data) {
listeners.forEach(listener => listener(data));
}
};
}
const emitter = createEventEmitter();
emitter.on(msg => console.log("Received:", msg));
emitter.emit("Hello World!");💡 学习点:事件驱动设计 + 闭包数据隔离
🌳 大型项目建议(实战)
你可以尝试在以下开源项目中加入闭包的使用:
| 项目类型 | 建议 |
|---|---|
| 小型工具库 | 如 lodash 的一些方法(如 once, memoize) |
| 前端组件库 | React hooks 内部很多地方都用了闭包来保存状态 |
| 浏览器扩展 | 用闭包管理插件内部状态 |
| Node.js 工具 | 创建中间件时用闭包保持上下文 |
📚 推荐学习路径
| 阶段 | 目标 | 推荐资源 |
|---|---|---|
| 入门 | 理解闭包定义与基本用法 | MDN Closures |
| 进阶 | 实际应用场景 | 《Eloquent JavaScript》第5章 |
| 精通 | 深度理解作用域链与性能优化 | 《You Don't Know JS: Scope & Closures》 |
如果你需要我为你定制一份“闭包专项训练计划”或提供配套练习题,请告诉我你的当前水平和目标 😊