一图看清Javascript的原型链,可以收藏了

406 阅读2分钟

写iOS开发有几年了,除个别项目试用了过Swift,一直还是使用Objective C。直到最近新项目和前端一起使用React Native来写。对Javascript的原型链和Objective C的类、元类继承链总感觉有点相似。本文先理清一下Javascript的原型链,之后再进行对比。


为方便理解推导构造函数、原型、实例对象之间关系,画了下面这张Javascript的原型链图,图中画出了JS中最基本的两个原型和两个构造函数。并在中间举例了一个构造函数、原型及其实例之间关系,以及它们和四个基本元素之间的联系。

可以看到图右上角有四根不同颜色样式线,也就是里面所有元素之间的四种关系。


  1. new 构造函数创建实例对象

  2. 函数属性prototype指向自己对应原型

  3. 原型的constructor属性指向对应的构造函数

  4. 实例对象的__proto__属性指向自己的原型


图中右上是两个构造函数Functin,Object,由绿色文字表示,左下是两个原型对象红色文字表示。


在创建一个函数时,JS引擎会给它创建一个对应的原型,这种对应关系,在图中我使用了同样的形状和背景颜色来表示,也可以看到用一根蓝色和一根紫色的线分别代表prototype和constructor属性互相联系着。


所有的函数由Function函数创建,所以函数的__proto__属性也都指向了Function.Prototype原型,该原型上有call、apply、bind等方法,这也就是所有函数的这些方法的继承来源了,继承,是的就理解成__proto__指向谁就继承谁吧


所有的原型由Object函数创建,他们的__proto__属性所以也都指向了Object.Prototype原型,当然这是默认情况下,对函数的原型重新指向,修改继承关系,原型链在中间就多几个继承链了,但无论中间有几个,最终还是会指向Object.Prototype,毕竟只有Object.Prototype的__proto__值 为null,原型链只会结束于它,它不是Object构造函数创建的,而是引擎用C/C++语言最初创建的。


Function的原型属性prototype和__proto__指向的都是同一个原型对象,可这个原型打印出来还是个匿名函数,作为函数它的prototype却是undefined,这应该是JS里唯一的一个特例了。我们说A的__proto__的constructor指向B,意味着B创建了A,在这里Function的__proto__指向的constructor指回去了Function,仔细品一下,那这是Function创建了Function?


Function 是 built-in 的对象,也就是并不存在“Function对象由Function构造函数创建”这样会造成鸡生蛋蛋生鸡的问题了。