Skip to content

原型和原型链

提示

原型和原型链是 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 // true

4. 隐式原型 (__proto__)

每个对象(实例)都有一个 __proto__ 属性(ES 标准中称为 [[Prototype]]),指向创建该对象的构造函数的原型对象。

js
const p = new Person()
// 实例的隐式原型 === 构造函数的显式原型
p.__proto__ === Person.prototype // true

注意__proto__ 是非标准属性(虽然浏览器广泛支持)。推荐使用 Object.getPrototypeOf()Object.setPrototypeOf()

原型链 (Prototype Chain)

当访问一个对象的属性时:

  1. 先在对象自身查找。
  2. 如果没有找到,则沿着 __proto__ 指向的原型对象查找。
  3. 如果原型对象上也没找到,则继续沿着原型的 __proto__ 查找。
  4. 层层向上,直到找到原型链的顶端 null

这条由 __proto__ 串联起来的链条,就是原型链

原型链终点

所有普通对象的原型链最终都会指向 Object.prototype。 而 Object.prototype 的原型是 null

js
Object.prototype.__proto__ === null // true

特殊关系:Function 与 Object

JavaScript 中有一句名言:“一切皆对象”。函数也是对象,因此函数也有 __proto__

1. 所有函数都是 Function 的实例

包括 ObjectArrayDate 等内置构造函数,甚至 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 // true

3. 鸡生蛋还是蛋生鸡?

js
// Object 是 Function 的实例
Object instanceof Function // true

// Function 是 Object 的实例 (因为 Function.prototype 原型链最终指向 Object.prototype)
Function instanceof Object // true

总结图解

  1. 构造函数 Fnprototype 指向 原型对象
  2. 原型对象constructor 指回 构造函数 Fn
  3. 实例对象 obj__proto__ 指向 原型对象
  4. 原型对象 也是对象,它的 __proto__ 指向 Object.prototype
  5. 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

如有转载或 CV 的请标注本站原文地址