主题
原型和原型链
提示
原型和原型链是 JavaScript 核心机制之一,理解它们对于掌握对象模型、继承以及 this 指向至关重要。
核心概念
1. 构造函数 (Constructor)
构造函数本质上就是普通函数,但习惯上首字母大写,并配合 new 操作符使用,用于创建对象实例。
js
function Person(name) {
this.name = name
}
const person1 = new Person('fengfeng')
console.log(person1) // Person { name: 'fengfeng' }2. 原型对象 (Prototype)
每个函数(构造函数)都有一个 prototype 属性,指向一个对象,这个对象就是原型对象。
- 原型对象上的属性和方法会被该构造函数创建的所有实例共享。
js
function Person() {}
Person.prototype.name = 'fengfeng'
const p1 = new Person()
const p2 = new Person()
console.log(p1.name) // 'fengfeng'
console.log(p2.name) // 'fengfeng'3. 构造器 (Constructor Property)
每个原型对象都有一个 constructor 属性,指回关联的构造函数。
js
Person.prototype.constructor === Person // true4. 隐式原型 (__proto__)
每个对象(实例)都有一个 __proto__ 属性(ES 标准中称为 [[Prototype]]),指向创建该对象的构造函数的原型对象。
js
const p = new Person()
// 实例的隐式原型 === 构造函数的显式原型
p.__proto__ === Person.prototype // true注意:
__proto__是非标准属性(虽然浏览器广泛支持)。推荐使用Object.getPrototypeOf()和Object.setPrototypeOf()。
原型链 (Prototype Chain)
当访问一个对象的属性时:
- 先在对象自身查找。
- 如果没有找到,则沿着
__proto__指向的原型对象查找。 - 如果原型对象上也没找到,则继续沿着原型的
__proto__查找。 - 层层向上,直到找到原型链的顶端
null。
这条由 __proto__ 串联起来的链条,就是原型链。
原型链终点
所有普通对象的原型链最终都会指向 Object.prototype。 而 Object.prototype 的原型是 null。
js
Object.prototype.__proto__ === null // true特殊关系:Function 与 Object
JavaScript 中有一句名言:“一切皆对象”。函数也是对象,因此函数也有 __proto__。
1. 所有函数都是 Function 的实例
包括 Object、Array、Date 等内置构造函数,甚至 Function 自身,都是 Function 的实例。
js
Number.__proto__ === Function.prototype // true
Object.__proto__ === Function.prototype // true
Function.__proto__ === Function.prototype // true (Function 自己创造了自己?引擎层面的设定)2. Function.prototype 是个特例
Function.prototype 是一个函数(typeof Function.prototype === 'function'),但它没有 prototype 属性,且它的 __proto__ 指向 Object.prototype。
js
Function.prototype.__proto__ === Object.prototype // true3. 鸡生蛋还是蛋生鸡?
js
// Object 是 Function 的实例
Object instanceof Function // true
// Function 是 Object 的实例 (因为 Function.prototype 原型链最终指向 Object.prototype)
Function instanceof Object // true总结图解
- 构造函数
Fn有prototype指向 原型对象。 - 原型对象 有
constructor指回 构造函数Fn。 - 实例对象
obj有__proto__指向 原型对象。 - 原型对象 也是对象,它的
__proto__指向Object.prototype。 Object.prototype的__proto__指向null。
mermaid
graph TD
subgraph Constructor
Fn[构造函数 Fn]
end
subgraph Prototype
FnProto[Fn.prototype]
ObjProto[Object.prototype]
Null[null]
end
subgraph Instance
Inst[实例 instance]
end
Fn -->|prototype| FnProto
FnProto -->|constructor| Fn
Inst -->|__proto__| FnProto
FnProto -->|__proto__| ObjProto
ObjProto -->|__proto__| Null