FE-04-JavaScript 高级:闭包、原型链、异步、模块化
本节目标:深入理解 JS 核心机制:作用域链、闭包、原型链、this 绑定、Promise/async-await、模块系统。
1. 执行上下文与作用域
执行上下文(Execution Context) 是 JS 引擎执行代码的环境:
1 | var a = 1; |
三个层级:
- 全局执行上下文(最外层)
- 函数执行上下文(每个函数调用)
- Eval 执行上下文(eval 内)
执行栈(Call Stack):LIFO,最后调用的先返回。
2. 作用域链
1 | const global = 'global'; |
作用域链:当前作用域 → 父作用域 → … → 全局。
let/const 的块级作用域:
1 | { |
3. 闭包(Closure)
闭包 = 函数 + 其引用的词法环境:
1 | function makeCounter() { |
经典场景:
数据封装:
1 | function createWallet(initial) { |
循环中的闭包陷阱:
1 | // 错:所有输出 3 |
4. 原型链
**每个 JS 对象都有一个隐藏的 [[Prototype]]**(通过 __proto__ 或 Object.getPrototypeOf() 访问)。
1 | const obj = { a: 1 }; |
构造函数 + prototype:
1 | function Person(name) { |
原型链:
1 | alice (实例) |
ES6 class 语法糖:
1 | class Person { |
继承:
1 | class Animal { |
5. this 绑定
this 的值取决于调用方式,不是定义位置。
1 | // 1. 默认绑定(独立函数调用) |
优先级:new > 显式 > 隐式 > 默认
箭头函数没有自己的 this(继承外层):
1 | const obj = { |
6. 异步编程
6.1 回调函数(Callback)
1 | fs.readFile('a.txt', (err, data) => { |
回调地狱:
1 | fs.readFile('a', (err, a) => { |
6.2 Promise
1 | const p = new Promise((resolve, reject) => { |
链式调用:
1 | fetch('/api/user') |
静态方法:
1 | Promise.all([p1, p2, p3]) // 全部成功才成功 |
6.3 async/await
async function 返回 Promise,await 等待 Promise resolve:
1 | async function loadUser(id) { |
并发 vs 串行:
1 | // 串行:依次等待 |
6.4 手写 Promise
1 | class MyPromise { |
7. 模块化
7.1 演进历史
- IIFE(ES5 之前)
- CommonJS(Node.js)
- AMD(RequireJS,已淘汰)
- UMD(兼容 CommonJS 和 AMD)
- ES Modules(ES6+,浏览器原生)
7.2 CommonJS(Node.js)
1 | // math.js |
特点:
- 同步加载
- 运行时解析
- 缓存已加载模块
7.3 ES Modules
1 | // math.js |
特点:
- 静态分析(编译时优化)
- 异步加载
- 浏览器原生支持
- Tree-shakable
7.4 动态导入
1 | // 按需加载 |
7.5 CommonJS vs ESM 互操作
1 | // ESM 引入 CJS |
8. 防抖与节流
1 | // 防抖(debounce):N 秒内只执行最后一次 |
9. 深拷贝
1 | // 浅拷贝 |
JSON.parse(JSON.stringify(obj)) 的问题:
- 丢失函数、
undefined、Symbol - Date 变字符串
- 循环引用会爆栈
10. JS 内存管理
内存生命周期:
- 分配(声明变量、对象)
- 使用(读写)
- 释放(GC)
GC 算法:现代浏览器用标记-清除(Mark-Sweep):
- 定期从根对象(window)开始遍历
- 不可达的对象标记为可回收
- 在适当时机清除
内存泄漏常见原因:
1 | // 1. 意外的全局变量 |
检测内存:
- Chrome DevTools → Memory → Heap snapshot
performance.memory.usedJSHeapSize(Chrome only)
小结
| 概念 | 关键点 |
|---|---|
| 作用域 | 全局/函数/块级 |
| 闭包 | 函数 + 词法环境,封装数据 |
| 原型链 | __proto__ 链,方法查找路径 |
| this | 调用时决定,不是定义时 |
| Promise | 三态、then/catch/finally |
| async/await | 同步写法 + 异步语义 |
| 模块化 | ESM 是未来,CJS 是历史 |
| 内存 | 标记清除 GC,避免泄漏 |
下一节讲 TypeScript 进阶:泛型、条件类型、类型体操。
- 本文作者: CoderSong
- 本文链接: https://jack-song-gif.github.io/2026/09/28/FE-04-JavaScript高级/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!