一文读懂 JS 原型链

开篇先放大招:

总结起来 JS 的原型链就只有两条规则:

  1. 构造对象 的原型指向 构造函数 的 prototype 属性。
  2. Object.prototype 的原型不可更改且指向 null(原型链的尽头)。

这有点类似于数学归纳法:先有一个初始条件,再有一套递归规则。接下来,我会用几个例子来证明这个观点。

JS 中最重要的三个数据结构就是对象、函数和数组。下面我将分别捋清这 3 类对象的原型链。

相信你一定看过这张图来源:www.cnblogs.com/dreamcc/p/1...

这张图虽然画得不错,但对于初学者来说,更像是一堆零碎知识点的堆叠。其实,关于原型链,核心规则就是我上面说的那两条。接下来我们来验证。

对象

一个普通对象 {} 是由 Object 这个构造函数构造出来的。根据第一条规则,构造对象的原型会指向构造函数的 prototype 属性,所以:

javascript 复制代码
console.log(Object.getPrototypeOf({}) === Object.prototype); // true

而 Object 本身又是一个函数。函数都是通过 Function 构造出来的,所以:

javascript 复制代码
console.log(Object.getPrototypeOf(Object) === Function.prototype); // true

Object.prototype 的值是一个对象。按理来说,所有对象都应该通过 Object 构造出来,但这里为了避免循环,规范对它做了特殊处理,让它的原型直接指向 null:

javascript 复制代码
console.log(Object.getPrototypeOf(Object.prototype) === null); // true

PS:这里补充一个知识点。null 可以理解为空对象,undefined 可以理解为空值。这里会涉及 JS 中的原始值,不懂的同学可以去 MDN 上看一看。

数组

一个普通数组是由 Array 这个函数构造出来的,所以:

javascript 复制代码
console.log(Object.getPrototypeOf([]) === Array.prototype); // true

和上面的 Object 一样,Array 本身也是一个函数,所以:

javascript 复制代码
console.log(Object.getPrototypeOf(Array) === Function.prototype); // true

Array.prototype 是一个对象,而对象都是由 Object 构造的。这里和 Object.prototype 不一样,需要注意:

javascript 复制代码
console.log(Object.getPrototypeOf(Array.prototype) === Object.prototype); // true

函数

无论是普通函数还是箭头函数,它们默认都是由 Function 这个函数构造出来的,所以:

javascript 复制代码
function fnc() {
  return 0;
}

const arrFnc = () => {
  return 0;
};

console.log(Object.getPrototypeOf(fnc) === Function.prototype); // true
console.log(Object.getPrototypeOf(arrFnc) === Function.prototype); // true

Function.prototype 是一个对象,所以:

javascript 复制代码
console.log(Object.getPrototypeOf(Function.prototype) === Object.prototype); // true

constructor

constructor 这部分的规则也比较简单,首先我们要知道,设置 constructor 属性的目的是什么。

假设我现在有一个对象,想知道它是如何构造出来的,那我应该怎么找?

假设有这样一种情况:

javascript 复制代码
class Person {
  constructor(name: string) {
    this.name = name;
  }

  name: string = '';
}

const person = new Person('bo');

console.log(Object.getPrototypeOf(person) === Object.prototype); // false

难道我要把项目里所有的 class 都遍历一遍,才能找到它是谁构造出来的吗?显然不现实。constructor 的意义就在这里,它提供了一条可以快速回溯到构造函数的路径。

javascript 复制代码
class Person {
  constructor(name: string) {
    this.name = name;
  }

  name: string = '';
}

const person = new Person('bo');

console.log(Object.getPrototypeOf(person).constructor === Person); // true

const copyPerson = Object.getPrototypeOf(person).constructor;
const child = new copyPerson('child');

console.log(child.name); // child
console.log(Object.getPrototypeOf(child) === Object.getPrototypeOf(person)); // true

总结一下,constructor 的作用就是让你可以通过原型链快速找到对应的构造函数,所以这里形成了一个回环结构。

flowchart LR instance["instance"] proto["Class.prototype"] cls["Class"] instance -->|"__proto__"| proto proto -->|"constructor"| cls cls -->|"prototype"| proto cls -->|"create"| instance

了解了这四个部分之后,就能和前面那种大图一一对上了。总结来说,原型链的知识其实并不复杂。它看起来乱,是因为相关概念比较分散,但底层规则并不复杂。学习编程和学习数学一样,关键是把握规律;如果只是死记硬背,思路就会越学越乱。

补充

为了方便讲解,文章里有些地方采用了不那么严谨的说法。这里先列出一部分,如果有遗漏,也欢迎各位同学指出:

  1. 不是所有对象的原型都指向 Object.prototype,只有默认创建出来的对象通常是这样。比如直接字面量创建,或者仅仅调用 Object()。你也可以使用 Object.create 在创建对象时指定原型,还可以在创建之后使用 Object.setPrototypeOf 更改对象原型,但这些都不违背我上面总结的那两条规则。
  2. 普通函数和箭头函数的区别,我会在以后的文章里再写;但在原型这一节里,你可以先把它们看作没有本质区别。
  3. 我提出的这两点关于原型链的总结,只是我个人当前的理解。如果有我没有覆盖到的地方,也欢迎大家积极评论,帮我找出错误,我们一起进步。
相关推荐
程序员大阳22 分钟前
副队长JavaScript教程(50)-DOM:网页开发的起点
javascript·dom·es·节点·概念·document·关系
香芋芋圆5 小时前
iD-editor 详解|OSM官方在线编辑器,基于D3.js的轻量地图编辑器
开发语言·javascript·编辑器
晗夜未央7 小时前
任务队列反复失败,先分清重试、阻塞和结果待核对
开发语言·javascript
jktantan7 小时前
每个节点 41 字节:把一棵百万节点树拆进 14 个 typed array
前端·javascript·vue.js·算法·typescript
我命由我123458 小时前
访客系统形式(有用户概念、无用户概念)
java·开发语言·前端·javascript·python·产品运营·产品经理
程序员大阳9 小时前
副队长JavaScript教程(65)-详解JSON:轻量级数据交换格式
javascript·json·序列化·反序列化·stringify·parse
paopaokaka_luck10 小时前
基于springboot+vue的益暖微光公益服务平台(DeepSeek公益助手、善款信息追溯、志愿服务积分闭环、ECharts运营分析、活动状态自动流转)
java·前端·javascript·spring boot·mysql·架构·echarts
栀椩10 小时前
Electron 内嵌页面跨域问题(CORS/PNA)解决全记录
前端·javascript·electron
SEO_juper11 小时前
Chrome 扩展一键查看当前页面 SEO 信息:不用切页面,点一下全出来
前端·javascript·chrome
Highcharts.js11 小时前
CSUN 2026|Highcharts无障碍数据与AI分享
javascript·人工智能·数据分析·highcharts·图表开发