文章目录
- JavaScript 核心知识体系全景总结
-
- 一、执行上下文:代码运行的环境基石
-
- 1. 三类执行上下文
- 2. 执行栈(调用栈)
- 3. 执行上下文的生命周期
-
- (1)创建阶段(函数调用后、代码执行前)
- (2)执行阶段
- 二、作用域与作用域链:变量访问的静态规则
-
- 1. 三类作用域
- 2. 词法作用域(静态作用域)
- 3. 作用域链
- 三、闭包:作用域与生命周期的交叉产物
-
- 1. 形成闭包的三个必要条件
- 2. 闭包的底层本质
- 3. 典型应用场景
- 4. 注意事项
- 四、this 指向:执行上下文的动态主体
-
- 1. 六大场景的 this 指向
- 2. `new` 操作符的执行过程
- 3. this 绑定优先级(从高到低)
- 4. 箭头函数的 this 特性
- 五、call / apply / bind:this 的手动控制
-
- 1. 三者核心对比
- 2. 关键注意点
- 3. 经典应用场景
- 六、原型与原型链:对象的属性查找机制
-
- 1. 核心概念与三角关系
- 2. 原型链
- 3. 标准 API 与误区
- 七、继承:基于原型链的代码复用方案
-
- 1. 七种继承方案演进
-
- (1)原型链继承
- (2)构造函数继承(借调)
- (3)组合继承
- (4)原型式继承
- (5)寄生式继承
- (6)寄生组合式继承(ES5 最优方案)
- (7)ES6 Class 继承(语法糖)
- 八、知识体系整体关联

JavaScript 核心知识体系全景总结
以下从运行机制、变量访问、执行主体、对象模型四大维度,系统性梳理原型链、继承、闭包、作用域、执行上下文、this指向、call/apply/bind 七大核心概念,并明确各知识点的内在关联与底层逻辑。
一、执行上下文:代码运行的环境基石
核心定义:JavaScript 引擎执行代码时的运行环境单元,包含代码执行所需的全部信息(变量、函数、作用域链、this 等),是 JS 运行机制的最小单位。
1. 三类执行上下文
- 全局执行上下文:程序启动时唯一创建,全局代码均在此环境运行。浏览器中对应 window,Node 中对应 globalThis。
- 函数执行上下文:函数被调用时动态创建,每次调用生成独立的新上下文。
- Eval 执行上下文:eval() 函数执行时创建,存在安全与性能问题,工程中极少使用。
2. 执行栈(调用栈)
- 遵循**后进先出(LIFO)**原则,管理所有执行上下文的生命周期。
- 程序启动时全局上下文入栈;函数调用时函数上下文入栈;函数执行完毕后上下文出栈,控制权回到上一层。
3. 执行上下文的生命周期
分为创建阶段和执行阶段两个步骤:
(1)创建阶段(函数调用后、代码执行前)
变量提升、函数提升的本质:创建阶段 VO 已完成声明收集,因此代码执行前即可访问声明。
(2)执行阶段
完成变量赋值、函数引用与逐行代码执行;执行完毕后上下文出栈,等待垃圾回收。
二、作用域与作用域链:变量访问的静态规则
核心定义:作用域是变量和函数的可访问范围,是一套静态语法规则,在代码定义时就已确定,与执行位置无关。
1. 三类作用域
- 全局作用域:最外层作用域,全局变量随处可访问,页面关闭才销毁。
- 函数作用域:函数内部声明的变量仅在函数内部可访问,外部无法直接读取。
- 块级作用域(ES6):由 {} 包裹,通过 let/const 声明的变量仅在当前代码块内生效,存在暂时性死区(TDZ),不存在变量提升。
2. 词法作用域(静态作用域)
JavaScript 采用词法作用域:函数的作用域在函数定义时就已固化,和调用位置、调用方式无关。与之相对的是动态作用域(如 bash 脚本),作用域在调用时才确定。
3. 作用域链
- 定义:访问变量时,JS 引擎从当前作用域开始,逐级向上追溯上层作用域,直到全局作用域,这个链式查找结构就是作用域链。
- 查找规则:就近原则,内层可访问外层,外层不可访问内层;同名变量内层覆盖外层。
- 本质:作用域链是执行上下文的核心组成部分,其结构由词法作用域静态决定。
三、闭包:作用域与生命周期的交叉产物
核心定义:闭包是函数与其词法作用域的组合。当内部函数引用了外部函数的变量,且内部函数在外部函数执行完毕后依然存活(被返回/被外部持有),就形成了闭包。
1. 形成闭包的三个必要条件
2. 闭包的底层本质
外部函数执行完毕后,其执行上下文会出栈,但外部函数的活动对象(AO)不会被垃圾回收——因为内部函数的作用域链仍然持有对它的引用。
3. 典型应用场景
let count = 0;
return {
increment: () => count++,
getCount: () => count
};
}
4. 注意事项
- 内存泄漏风险:闭包会长期持有外部作用域引用,若不当使用(如循环引用、持有大对象)会导致内存无法释放;
- 箭头函数同样可以形成闭包,且其 this 继承自外层词法作用域。
四、this 指向:执行上下文的动态主体
核心定义:this 是执行上下文的内置属性,指向当前代码的执行主体。this 的指向在函数调用时动态确定,与函数定义位置无关。
1. 六大场景的 this 指向
| 全局环境直接执行 | 全局对象(浏览器 window / Node globalThis) | 严格模式下为 undefined |
| 普通函数直接调用 | 全局对象 | 严格模式下为 undefined |
| 对象方法调用 | 调用该方法的对象 | 谁调用,就指向谁 |
| 构造函数调用(new) | 新创建的实例对象 | new 会创建空对象并绑定 this |
| 箭头函数 | 定义时外层词法作用域的 this | 无自身 this,不可被修改 |
| DOM 事件处理函数 | 绑定事件的 DOM 元素 | addEventListener 回调默认指向元素 |
2. new 操作符的执行过程
3. this 绑定优先级(从高到低)
new 绑定 > bind 绑定 > call/apply 绑定 > 对象方法调用 > 默认绑定(普通函数调用)
4. 箭头函数的 this 特性
- 没有自身的 this、prototype、arguments,不能作为构造函数;
- this 继承自定义时外层作用域的 this,且无法通过 call/apply/bind 改变。
五、call / apply / bind:this 的手动控制
三者都是 Function.prototype 上的原生方法,核心作用是手动修改函数内部的 this 指向,是 this 动态绑定的核心 API。
1. 三者核心对比
| call(thisArg, arg1, arg2, …) | 立即执行 | 参数逐个传递 | 函数执行结果 | 改变 this 并立即调用 |
| apply(thisArg, argsArray) | 立即执行 | 参数以数组/类数组传递 | 函数执行结果 | 适合参数数量不确定的场景 |
| bind(thisArg, arg1, arg2, …) | 不立即执行,返回新函数 | 参数可分批传递(柯里化) | 绑定了 this 的新函数 | 永久绑定 this,支持延迟执行 |
2. 关键注意点
- 若 thisArg 传入 null/undefined,非严格模式下 this 会指向全局对象,严格模式下为传入的值;
- 箭头函数调用三者无效,无法修改其 this;
- 多次 bind 只有第一次生效,后续绑定不会覆盖。
3. 经典应用场景
六、原型与原型链:对象的属性查找机制
核心定义:原型是 JavaScript 实现面向对象的核心机制,原型链是对象属性/方法的查找规则,也是继承的底层基础。
1. 核心概念与三角关系
所有对象与函数都遵循原型三角关联:
核心公式:
实例.__proto__ === 构造函数.prototype
构造函数.prototype.constructor === 构造函数
2. 原型链
- 定义:原型对象本身也是普通对象,同样拥有自己的 __proto__,指向其构造函数的原型;层层向上追溯,直到 Object.prototype.__proto__ === null,这条链式结构就是原型链。
- 属性查找规则:访问对象属性时,先查找对象自身;找不到则沿 __proto__ 向上遍历原型链;到顶端仍未找到则返回 undefined。
- 属性遮蔽:对象自身属性与原型属性同名时,优先读取自身属性。
3. 标准 API 与误区
- __proto__ 是浏览器实现的非标准属性,工程中推荐使用:
- Object.getPrototypeOf(obj):获取对象原型
- Object.setPrototypeOf(obj, proto):设置对象原型
- 所有函数的默认原型都是 new Object(),因此原型链最终都会指向 Object.prototype。
七、继承:基于原型链的代码复用方案
JavaScript 的继承本质是基于原型链的代码复用,经历了多个演进阶段,最终形成成熟的最优方案。
1. 七种继承方案演进
(1)原型链继承
- 实现:Child.prototype = new Parent()
- 缺陷:父类引用属性被所有子类实例共享;创建子类时无法向父类传参。
(2)构造函数继承(借调)
- 实现:子类构造函数内执行 Parent.call(this, …args)
- 优点:可传参、避免引用共享;
- 缺陷:只能继承实例属性,无法继承父类原型方法,方法无法复用。
(3)组合继承
- 实现:原型链继承方法 + 构造函数继承属性
- 缺陷:调用两次父类构造函数,子类原型上存在多余的父类实例属性。
(4)原型式继承
- 实现:基于已有对象创建新对象,对应 ES6 Object.create()
- 缺陷:引用属性仍然被所有新对象共享。
(5)寄生式继承
- 实现:在原型式基础上封装函数,为对象新增方法
- 缺陷:方法无法复用,每个对象都有独立副本。
(6)寄生组合式继承(ES5 最优方案)
- 核心:子类原型继承父类原型的副本,不重复调用父类构造函数function inherit(Child, Parent) {
const proto = Object.create(Parent.prototype);
proto.constructor = Child;
Child.prototype = proto;
} - 优势:仅调用一次父类构造函数,无冗余属性,完整保留原型链结构。
(7)ES6 Class 继承(语法糖)
- 语法:class Child extends Parent { constructor() { super(); } }
- 本质:底层仍然是寄生组合式继承,super() 对应构造函数借调,extends 对应原型链关联。
- 特性:class 必须通过 new 调用,无变量提升;静态方法通过 static 声明,继承自父类本身。






