JavaScript OOP的核心是原型链、函数对象可扩展性与闭包作用域;原型链实现继承共享,构造函数+new完成实例化,闭包提供真正私有性,class仅为原型操作的语法糖。

JavaScript 面向对象编程(OOP)没有传统类语言的“类加载器”或“虚拟机字节码”,它的核心设计模式全部运行在解释执行+即时优化(如V8的TurboFan)之上,底层依赖三个不可替代的机制:原型链、函数对象的可扩展性、以及执行上下文与闭包形成的私有作用域。理解这些,才能真正看懂单例、工厂、构造器、组合、代理等模式为何能“不靠语法糖而成立”。
原型链:继承与共享的唯一基础设施
JavaScript中不存在“类定义编译期”,所有继承本质都是对象间[[Prototype]]内部槽的指向关系。Object.create()、构造函数的prototype属性、class extends语句,最终都归结为设置一个对象的隐式原型(__proto__)指向另一个对象。
关键细节:
- 每个函数对象自动拥有prototype属性(初始为{constructor: fn}),该对象将成为用new调用时实例的[[Prototype]]
- 访问属性时引擎执行的是“自有属性 → [[Prototype]] → [[Prototype]].[[Prototype]] … → null”的线性查找,不是“类模板展开”
- 修改父级prototype上的方法,所有已存在实例立即生效——这是动态原型的本质,也是Vue 2响应式、Lodash工具函数热替换的基础
构造函数 + new:实例化过程的四步原子操作
执行new Foo()不是语法糖,而是严格定义的抽象操作:① 创建空对象;② 设置其[[Prototype]]为Foo.prototype;③ 以该对象为this执行Foo();④ 若Foo返回对象则用它,否则返回新对象。
立即学习“Java免费学习笔记(深入)”;
这意味着:
- 构造函数本身是普通函数,只是被new调用时获得特殊行为
- this绑定发生在第③步,所以箭头函数不能作构造函数(无this绑定能力)
- 手动return {}会覆盖默认返回,但return原始值(如return 42)无效——这是实现“强制实例化”的底层保障
闭包与模块作用域:封装与私有性的实际载体
JavaScript没有private关键字(ES2022 #字段是语法糖,底层仍靠闭包模拟),真正的私有性来自词法环境(Lexical Environment)的不可访问性。
例如单例模式:
const Singleton = (function() {
let instance = null; // 外层函数的私有变量
return function() {
if (!instance) instance = { data: Date.now() };
return instance;
};
})();
这里instance无法从外部读写,不是因为“修饰符”,而是因为JS引擎规定:内部函数可访问外层执行上下文的变量对象,而外部代码永远无法反向进入那个已销毁/不可见的上下文。
Class语法:仅是原型操作的声明式封装
ES6 class不是新机制,Babel转译后就是构造函数+Object.setPrototypeOf()调用。比如:
class A { method() {} }
class B extends A { }
等价于:
-
B.prototype.__proto__ = A.prototype(设置原型链) -
Object.setPrototypeOf(B, A)(设置静态继承,让B可调用A的静态方法) - constructor内super()实际调用
A.call(this, ...)
因此,class不能改变JavaScript的原型本质,它只是让开发者更少出错地操作那条链。



















