JavaScript 原型链

基础知识 · 2022-02-19 · 198 人浏览

先说结论

  • 每个构造函数都有一个原型对象
  • 原型原型有一个属性指回构造函数
  • 实例对象有一个内部指针指向原型对象

原型链图示

我是倒着去理解原型链的,先根据原型链现有的状态(规则),逐步深入去刨析它们之间的关系。拿下面这个图来看,Foo、Object、Function 是构造函数,它们满足这样的关系:

  • 每个构造函数都有一个原型对象 (prototype),在图中用紫色文字箭头指示;
  • 原型有一个属性指回构造函数 (constructor),在图中用绿色文字箭头指示;
  • 实例有一个内部指针指向原型 (__proto__),在图中用褐色文字箭头指示。

显然,要搞清楚原型链,必须要了解 (__proto__),prototype,constructor。


关于__proto__

每个对象都有一个 (__proto__) 属性指向构造函数的 prototype

从对象开始,对象可不止是这样的:

let obj = {};

在 JavaScript 中,除了基本数据类型外,其他的一切都是对象。通过 function 关键字定义的函数、通过 let、const 声明的用花括号包裹的变量、通过 class 关键字定义的类,都可看作是对象。

既然是对象(实例),它就会遵循原型链规则,内部有一个 (__proto__) 属性指向构造函数的原型。可以在上图中得到验证:图中共有 8 个 (__proto__),对应着 (f1 f2)、(o1 o2)、Foo、Object、Function 以及 3 个不同的 prototype。


关于 prototype(原型)

只有函数才有且必然有 prototype

函数和对象是什么关系呢?函数就是对象,函数是对象的一个子集。因此,函数不仅有 prototype,还有 (__proto__),前者是其作为函数的特征,后者是其作为对象的特征。在上图中,三个函数 Foo、Object、Fucntion 都有 prototype,非函数类型的对象没有 prototype。

函数能够通过 new 来构造自己的实例,就是把自己的 prototype 的引用交给了实例,使得实例能够通过__proto__属性来访问自己的原型。


关于 constructor

它存在于 prototype 中,是对构造函数的引用。构造函数能够通过 prototype 属性找到自己的原型,原型可以通过自己的 constructor 属性找到构造函数,这是一个双向的过程。通过构造函数创建了实例,那么实例便可通过__proto__找到构造函数。


总结 读书笔记
Theme Jasmine by Kent Liao