⚡ 编程实验室🏗️ HTML🎨 CSS⚡ JavaScript🐍 Python🗄️ SQL☕ Java⚛️ React💚 Vue🟢 Node.js⚙️ C语言🐘 PHP🐹 Go🔷 TypeScript🐬 MySQL🔧 C++🎯 C#🦀 Rust🅱️ Bootstrap💡 jQuery🎸 Django🍃 MongoDB👗 Sass🎪 Kotlin📊 R语言📋 XML📊 Excel🐘 PostgreSQL🐳 Docker🅰️ Angular🎮 游戏🏠 网站首页

JavaScript 闭包

理解闭包——函数记住外部变量的能力 · 难度:高级 · +15XP

JavaScript 闭包深入理解

闭包(Closure)是 JavaScript 最核心的概念之一。当一个函数能够"记住"并访问其词法作用域(lexical scope)中的变量,即使该函数在其词法作用域之外被调用时,就形成了闭包。闭包是函数式编程的基础,广泛用于数据封装、模块化、回调函数、柯里化等场景。

闭包的形成条件

  1. 函数嵌套:内部函数引用外部函数的变量
  2. 内部函数被返回到外部作用域或被传递给其他函数
  3. 外部函数执行完毕后,内部函数仍持有对外部变量的引用
// 经典闭包示例
function createCounter() {
  let count = 0;  // 被闭包"捕获"的变量

return function() { count++; // 访问外部作用域的变量 return count; }; }

const counter1 = createCounter(); console.log(counter1()); // 1 console.log(counter1()); // 2 console.log(counter1()); // 3

const counter2 = createCounter(); console.log(counter2()); // 1(独立的闭包,有自己独立的 count)

// count 变量被"封闭"在返回的函数中 // 外部无法直接访问,但函数可以持续访问和修改 console.log(typeof count); // "undefined"(外部不可见)

闭包的实战应用

应用场景说明示例
数据封装/私有变量隐藏内部状态计数器、缓存
函数工厂生成特定行为的函数乘法器、格式化工具
模块模式封装方法和私有数据IIFE + 闭包
事件处理保持对循环变量的引用for 循环 + 闭包
// 应用1: 函数工厂
function multiplyBy(factor) {
  return function(number) {
    return number * factor;
  };
}
const double = multiplyBy(2);
const triple = multiplyBy(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15

// 应用2: 模块模式(利用闭包实现私有变量) const User = (function() { let privateId = 0;

return { create(name) { privateId++; return { id: privateId, name }; }, getTotal() { return privateId; } }; })(); const u1 = User.create("张三"); const u2 = User.create("李四"); console.log(u1.id); // 1 console.log(User.getTotal()); // 2 console.log(typeof privateId); // "undefined"(外部不可访问)

// 应用3: 解决经典的 for 循环闭包陷阱 for (var i = 1; i <= 3; i++) { setTimeout((function(j) { return function() { console.log(j); }; })(i), i * 1000); } // 输出: 1, 2, 3(而不是 4, 4, 4) // 现代写法:用 let 代替 var 即可

Ctrl+Enter
🚀 升级VIP
解锁全部课程+AI助手

🏆 学习排行

加载中...

📊 统计

📖 231 篇
0 完成
🔥 0