红宝书第六讲:作用域链与闭包:厨房里的调味料架原理

红宝书第六讲:作用域链与闭包:厨房里的调味料架原理

资料取自《JavaScript高级程序设计(第5版)》。 查看所有教程:红宝书学习大纲


一、什么是作用域链?(洋葱层级结构)

想象你在厨房做菜,每个调料瓶按使用频率由近到远摆放:

  1. 当前厨房台面:手边的盐、酱油 → 相当于函数内部变量(局部作用域)
  2. 冰箱里的辣椒酱:常用但稍远 → 外层函数的变量(父级作用域)
  3. 储藏室的大米:最远的储备 → 全局变量(全局作用域)

作用域链的查找顺序

javascript 复制代码
function 厨房() {
  const 盐 = "适量盐"; // 第二层作用域

  function 炒菜() {
    console.log(盐); // ✅ 能找到冰箱里的盐
    console.log(大米); // ✅ 能找到储藏室的大米
  }
  
  炒菜();
}

const 大米 = "5kg"; // 第三层(全局)
厨房();

二、闭包:私人调料罐

闭包就像你出门前把常用调料装进便携罐带走:

  • 定义:内部函数保留外部变量的引用,"保鲜"这部分变量的值。
  • 关键特点:即使外层函数已执行完毕,闭包仍然能访问其变量。

代码示例

javascript 复制代码
function 制盐机() {
  let 盐堆存量 = 1000;   // 盐堆存量被内部函数"锁住"

  return function 取盐(需要量) {
    盐堆存量 -= 需要量;  // 每次取盐减少存量
    console.log(`剩余盐量:${盐堆存量}g`);
  };
}

const 我的取盐动作 = 制盐机();
我的取盐动作(100);  // 剩余盐量:900g
我的取盐动作(200);  // 剩余盐量:700g
  • 分析制盐机()执行后,本应销毁的盐堆存量取盐函数保留,形成闭包[^3]。

三、闭包的两面性

益处

  1. 数据保护 :避免变量全局污染,如封装计数器:

    javascript 复制代码
    function 创建计数器() {
      let count = 0;
      return () => ++count; // 只能通过闭包修改
    }
    const 计数器 = 创建计数器();
    计数器(); // 1

潜在问题

  • 内存泄漏:如果闭包引用大型数据且未被释放,可能影响性能:

风险示例

javascript 复制代码
function 加载大数据() {
  const 大数据 = new Array(1000000).fill('🚗'); // 内存大户

  return function 处理函数() {
    // 即使不再需要大数据,闭包仍保留引用
  };
}
let 保存闭包 = 加载大数据();
保存闭包 = null; // ✅ 需手动解除引用

四、生活中的闭包场景

  1. 按钮点击统计:记录用户点击按钮次数。

  2. 接口请求防重复:闭包保存最后一次请求标识。

  3. 模块化开发 :借助IIFE(立即执行函数)封闭作用域:

    javascript 复制代码
    const 模块 = (function() {
      const 内部数据 = "私有";
    
      return {
        get数据: () => 内部数据
      };
    })();
    
    console.log(模块.get数据()); // '私有'

目录:总目录 上篇文章:红宝书第五讲:函数声明与表达式小白详解

总结与练习

  • 理解步骤:先画作用域层级 → 再看闭包如何抓取变量。
  • 练习:实现一个缓存计算结果的闭包函数。

重要提醒:闭包虽强大,但控制引用范围,避免内存包袱过重!

相关推荐
小小弯_Shelby几秒前
uniApp App内嵌H5打开内部链接,返回手势(左滑右滑页面)会直接关闭H5项目
前端·uni-app
IT_陈寒3 分钟前
SpringBoot性能飞跃:5个关键优化让你的应用吞吐量提升300%
前端·人工智能·后端
加洛斯1 小时前
Vue 知识篇(2):浅谈Vue中的DOM与VNode
前端·javascript·vue.js
kunge1v51 小时前
学习爬虫第三天:数据提取
前端·爬虫·python·学习
可爱的秋秋啊1 小时前
简单网站编写
开发语言·前端
Keepreal4961 小时前
Electron基本概念
前端·javascript·electron
zhaoolee1 小时前
Claude Code使用指北(如何白嫖百万Qwen3 Token,每月劲省20刀)
前端
前台端水工程师1 小时前
vite-plugin-mock插件的3.0.2版本在生产环境无法使用
前端
戈卬2 小时前
VSCode 中 Prettier 工作原理与使用指南
前端
我叫张得帅2 小时前
从零开始的前端异世界生活--005--“HTTP详细解析中”
前端