Skip to content

当然可以!以下是从入门到精通的 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》

如果你需要我为你定制一份“闭包专项训练计划”或提供配套练习题,请告诉我你的当前水平和目标 😊

Released under the ISC License.