所属板块:3. 原型与面向对象(OOP)
记录日期:2026-03-xx
更新:遇到 new 操作符或手写题时补充
1. 对象创建模式的演进史(从笨到精)
JS 没有真正的“类”,对象是逐步进化出来的:
-
字面量 / Object() 构造函数
const obj = { name: "张三" }; // 最简单缺点:无法批量生产同类对象。
-
工厂模式(Factory Pattern)
function createPerson(name) { return { name, say() { console.log(this.name); } }; }缺点:无法识别对象类型(
instanceof失效)。 -
构造函数模式(Constructor Pattern)
function Person(name) { this.name = name; this.say = function() { console.log(this.name); }; }缺点:每个实例的方法都在内存里重复一份,浪费内存。
-
原型模式(Prototype Pattern)
把共享方法放到Person.prototype上。
缺点:引用类型属性会被所有实例共享(容易被意外修改)。 -
组合模式(构造函数 + 原型) —— JS 中最推荐的自定义对象方式
- 私有/实例属性放构造函数
- 共享方法放原型
这就是 [3-1] 原型机制的实际应用。
2. new 操作符的底层四步曲(面试必考)
当执行 new Person(...) 时,JS 引擎实际做了以下四件事:
-
创建一个全新的空对象
let obj = {}; -
将新对象的
[[Prototype]](即__proto__)链接到构造函数的prototype
obj.__proto__ = Person.prototype; -
将构造函数的
this绑定到新对象,并执行构造函数代码
Person.call(obj, ...args); -
判断构造函数返回值
- 如果返回的是引用类型(对象/数组/函数等),则直接返回该引用
- 否则返回新创建的
obj
这就是为什么 new 能把普通函数变成构造函数。
3. 手写 myNew(面试高频手写题)
function myNew(Constructor, ...args) {
// 1. 创建空对象
const obj = Object.create(Constructor.prototype); // 一步完成第1、2步
// 2. 执行构造函数,绑定 this
const result = Constructor.apply(obj, args);
// 3. 返回逻辑
return result instanceof Object ? result : obj;
}
// 使用示例
function Person(name) {
this.name = name;
}
Person.prototype.say = function() { console.log(this.name); };
const p = myNew(Person, "李四");
p.say(); // "李四"
console.log(p instanceof Person); // true
(Object.create() 是最优雅的实现方式,面试时可直接用)
4. 小结 & 复习时的“缔造者视角”
- 对象创建的核心是:实例属性放构造函数,共享方法放原型
new的四步曲是理解后面继承和class语法的关键- [3-1] 的原型三角关系 + 本文的 new 操作符,共同构成了 JS 对象的完整创建机制
下一篇文章会进入 [3-3]:继承的血泪史(六种继承方式演进 + 寄生组合式继承手写)——这是整个板块最重的手写题部分。
返回总目录:戳这里