JavaScript 原型链理解

在 JavaScript 中,原型与原型链是理解继承机制、函数对象关系、实例对象行为最关键的基础。很多开发者在学习原型链时容易混淆“构造函数的 prototype” 与 “实例对象的 proto”,同时也会对 Function 和 Object 两大内置构造器的特殊性产生迷惑。本文将结合一张清晰的原型链关系图,从整体结构到底层机制,帮助你系统理解 JavaScript 的原型链。


一、三种关键关系

在深入原型链图之前,我们需要先理解三种不同指向关系,它们分别由三类线表示:

  1. 黑色线:构造函数 new 出来的实例对象
    实例对象由构造函数通过 new 关键字创建,黑色线代表这种“实例化关系”。

  2. 红色线:构造函数的 prototype 属性
    每一个函数(包括普通函数和内置构造函数)都有 prototype。
    prototype 是“构造函数 → 原型对象”的一条定向链接。

  3. 绿色线:对象的 proto 原型链指向
    任何对象都有一个内部属性 [[Prototype]](浏览器中表现为 __proto__),它形成原型链。
    绿色线表示“对象 → 上一层原型对象”的关系。

这些关系构成了本文中原型链图的基础。


二、从顶层开始:Function 与 Object 的特殊结构

JavaScript 中最特殊的两个构造函数是:

Function

Object

它们构成了所有对象、函数的顶层模型。

1. Function 构造函数的特殊性

(1) Function 构造函数 指向 Function.prototype

红线:

Function → Function.prototype

(2) Function 构造函数 指向 Object 构造函数

黑线:

Function → Object

因为 Object 也是函数,所有的函数都是通过 Function new 出来的。

(3) Function 自己的 proto 也指向 Function.prototype

绿色线:

Function.__proto__ === Function.prototype

这意味着:
Function 是所有函数的构造函数,同时又是自身的实例。(注:函数其实也是一个实例对象!)

这是 JavaScript 原型系统的最特别之处。


2. Object 构造函数的结构

(1) Object → Object.prototype

红线:

Object → Object.prototype

(2) Object → A.prototype

黑线:

Object → A.prototype

因为任何对象都是都是通过 Object new出来的,而这里的 A.prototype 也是一个对象。

(3) Object.prototype.proto 为 null

绿色线:

Object.prototype.__proto__ === null

这是整个原型链的终点。


三、普通构造函数 A 的原型结构

以一个普通构造函数 A 为例:

1. 构造函数 A 的 prototype(红线)

A → A.prototype

2. A.prototype.proto 的上层(绿色线)

A.prototype.__proto__ === Object.prototype

所有普通构造函数的 prototype 默认都继承自动自 Object.prototype。

3. A 的 proto(绿色线)

作为一个函数,A 本身也是 Function 的实例:

A.__proto__ === Function.prototype


四、实例对象 a 的原型链

当我们通过 new A() 创建实例:

const a = new A();

会形成两条关键关系:

1. 实例 a → A(黑色线)

表示 a 是由 A 构造而来。

2. 实例 a → A.prototype(绿色线)

a.__proto__ === A.prototype

此后 a 就能“沿着原型链”向上查找属性。


五、整张图的完整解析流程

结合文章开头的图,我们可以沿着三条线逐层理解整个体系:

1. 红线(prototype)

表示构造函数自身的 prototype:

  • Function → Function.prototype

  • Object → Object.prototype

  • A → A.prototype

prototype 是构造函数“赋予实例的共享属性”的集合。

2. 绿线(proto

表示某个“对象”的原型链向上查找路径:

  • 实例 a → A.prototype

  • A.prototype → Object.prototype

  • A → Function.prototype

  • Function.prototype → Object.prototype

  • Object.prototype → null

每个对象都有 proto,这形成了“继承链”。

3. 黑线(实例化)

表示 new 创建实例:

  • A → a

构造函数通过 new 生成实例,而实例只通过 proto 继承方法。


六、整体关系总结(最重要的图式心智模型)

你可以记住三句话:

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

包括 Function 自己:

函数.__proto__ === Function.prototype

2. 所有 prototype 的最终源头都是 Object.prototype

xxx.prototype.__proto__ === Object.prototype

3. Object.prototype 是唯一一个原型链终点

Object.prototype.__proto__ === null

这三条规则奠定了整个 JavaScript 原型链体系。


七、为什么理解这张图很重要?

如果你弄懂了这张图,你就能回答所有原型链相关问题:

  • 为什么函数有 call、apply?

  • 为什么对象可以使用 toString?

  • 为什么 Function instanceof Function 为 true?

  • 为什么 Function instanceof Object 也为 true?

这些都来自于原型链的结构。


八、结语

原型链是 JavaScript 继承体系的核心,而 Function 与 Object 的双重特殊结构则是整个模型中最值得深入理解的部分。本文基于一张清晰准确的原型链图,从顶层关系到实例对象,逐级解释 prototype、proto、构造函数三者之间的联系,希望能帮助你彻底掌握原型链概念。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐