通俗理解:“类的原型对象就是一块区域里有这个类的实例对象通用的属性和方法”
这就是 JavaScript 中原型(prototype)的核心作用和设计理念。
“一块区域” = 原型对象本身(如
String.prototype
,Array.prototype
,MyClass.prototype
):- 这是一个实实在在存在的 JavaScript 对象。
- 它就是为特定“类”(或更准确地说,为通过特定构造函数创建的对象)专门开辟的共享资源池。
“有...通用的属性和方法” = 原型对象上定义的属性和方法:
- 开发人员(或语言本身)会将所有该类型对象需要共享的功能(方法)和可能需要的共享数据(属性)放入这个“区域”中。
- 例如:
- 所有字符串都要会用
.toUpperCase()
,.slice()
→ 这些方法就存在String.prototype
这个“区域”里。 - 所有数组都要会用
.map()
,.filter()
,.push()
→ 这些方法就存在Array.prototype
这个“区域”里。 - 你自己定义了一个
Person
类,所有Person
实例都要能.sayHello()
→ 这个方法就定义在Person.prototype
这个“区域”里。
- 所有字符串都要会用
“实例对象通用的” = 通过原型链实现共享:
- 关键机制:当您通过
new Constructor()
创建一个实例(比如const myStr = new String('hello');
或const p = new Person('Alice');
),这个新对象内部会自动连接(指向)构造函数的prototype
对象(那个“区域”)。 - 当你访问这个实例的属性或方法时(如
myStr.toUpperCase()
或p.sayHello()
):- JavaScript 引擎会首先在实例对象自身属性中查找。
- 如果在实例自身没找到,它会自动去您说的那个“共享区域”(即原型对象)里去查找!
- 这个过程就是原型链查找。正是这个机制,使得所有实例都能复用定义在原型对象上的属性和方法,实现了您所说的“通用”。
- 关键机制:当您通过
1. 原型对象(Prototype Object)
✅ 定义:
"原型对象是每个JavaScript函数自带的prototype
属性指向的特殊对象。它存储了该构造函数创建的所有实例共享的属性和方法。"
✅ 核心特点:
- 是构造函数(类)的共享方法容器
- 通过
构造函数.prototype
直接访问 constructor
属性指回构造函数本身
2. 原型(Prototype)
✅ 定义:
"原型是JavaScript中每个对象内部维护的隐式继承链接(通过__proto__
或Object.getPrototypeOf()
访问)。它决定了属性和方法的查找路径。"
✅ 核心机制:
- 形成原型链(prototype chain)实现继承
- 属性查找规则:对象自身 → 原型链向上查找 → 终点
null
函数.prototype
是其实例的原型起点
原型对象和通过构造函数创建的实例对象
相同点:
都是对象(Object 类型)
class MyClass {}
const a = new String("hello"); // a 是字符串对象
const protoObj = MyClass.prototype; // protoObj 是原型对象console.log(typeof a); // "object"
console.log(typeof protoObj); // "object"
本质区别:
特征 | 普通对象 (如 a ) | 原型对象 (构造函数.prototype ) |
---|---|---|
创建方式 | new 构造函数() 或字面量 | 函数声明时自动创建 |
核心作用 | 存储数据/业务逻辑 | 作为共享方法的容器 |
特殊属性 | 无 | 必含 constructor 指向构造函数 |
内存中的角色 | 实例对象 | 其他对象的原型模板 |
示例 | a.indexOf("e") (数据操作) | String.prototype.indexOf = function(){} (方法定义) |
关键关系:
const str = new String("test");// 原型对象在继承链的上游
console.log(str.__proto__ === String.prototype, // true:实例的隐式原型指向原型对象str instanceof String // true:继承关系的体现
);// 原型对象本身也是普通对象
console.log(String.prototype instanceof Object // true:原型对象也是对象
);
总结:
"原型对象是特殊的共享容器对象,普通对象是数据载体。
当执行 var a = new String()
:
a
是实例对象(用于操作数据)String.prototype
是原型对象(存储所有字符串共享方法)
它们的共性是都是对象,差异在于在原型系统中的角色和定位不同。"
结论:
- 原型对象和实例对象都是对象,但原型对象是构造函数的属性,实例对象是构造函数创建的对象。
- 它们通过原型链连接:实例对象的隐式原型(
__proto__
)指向构造函数的原型对象(prototype
)。