🍭 图解原型和原型链

20190314150227.png

图解原型和原型链

原型和原型链是 JS 中不可避免须要碰到的知识点📕,本文使用图片思惟导图的形式缕一缕原型、原型链、实例、构造函数等等概念之间的关系🌚markdown

Constructor 构造函数

首先咱们先写一个构造函数 Person,构造函数通常为了区别普通函数要求首字母大写:函数

function Person(){}
复制代码

prototype 原型

原型指的就是一个对象,实例“继承”那个对象的属性。在原型上定义的属性,经过“继承”,实例也拥有了这个属性。“继承”这个行为是在 new 操做符内部实现的。spa

先不说实例,原型与构造函数的关系就是,构造函数内部有一个名为 prototype 的属性,经过这个属性就能访问到原型:prototype

20190314132908.png

Person 就是构造函数,Person.prototype 就是原型code

20190314132934.png

instance 实例

有个构造函数,咱们就能够在原型上建立能够“继承”的属性,并经过 new 操做符建立实例orm

20190314141908.png

比方说 Person,咱们要建立一个 person 实例,那么使用 new 操做符就能够实现,并经过 instanceof 来检查他们之间的关系:对象

20190314132309.png

咱们在原型上定义一个属性,那么实例上也就能够“继承”这个属性:继承

20190314133215.png

proto 隐式原型

实例经过 __proto__ 访问到原型,因此若是是实例,那么就能够经过这个属性直接访问到原型:图片

20190314141947.png

因此这二者是等价的:原型链

20190314142041.png

constructor 构造函数

既然构造函数经过 prototype 来访问到原型,那么原型也应该可以经过某种途径访问到构造函数,这就是 constructor:

20190314142246.png

所以二者的关系应该是这样:

20190314142755.png

注意这里的 constructor 是原型的一个属性,Constructor 指的才是真正的构造函数。二者名字不要弄混了😀

实例、构造函数、原型之间的关系

这里咱们能够看到若是实例想要访问构造函数,那么应当是:

20190314143125.png

没有从实例直接访问到构造函数的属性或方法:

20190314143254.png

实例与原型则是经过上文中提到的 __proto__ 去访问到。

在读取一个实例的属性的过程当中,若是属性在该实例中没有找到,那么就会循着 __proto__ 指定的原型上去寻找,若是还找不到,则尝试寻找原型的原型🐚:

20190314143837.png

咱们把注释删掉,给实例同名属性,能够看到打印出来的属性就指向这个:

20190314143944.png

原型链

原型一样也能够经过 __proto__ 访问到原型的原型,比方说这里有个构造函数 Person 而后“继承”前者的有一个构造函数 People,而后 new People 获得实例 p

当访问 p 中的一个非自有属性的时候,就会经过 __proto__ 做为桥梁链接起来的一系列原型、原型的原型、原型的原型的原型直到 Object 构造函数为止。

这个搜索的过程造成的链状关系就是原型链

20190314144733.png

以下图:

20190314145239.png

看到 null 了么,原型链搜索搜到 null 为止,搜不到那访问的这个属性就是不存在的:

20190314145540.png

以上,这就是原型、原型链、构造函数、实例、null 之间的关系。