1

最近在项目中经常遇到,且与同事经常探讨关于js原型链的知识。发现其实很多工作经验好多年的同事也记不太清楚原型链的整个环节,今天在这里专门的把链图画出来,并且加以讲解,希望能够帮到更多前端的朋友。

原型链其实就是一个三角关系,如下图所示,我们编写了一个构造函数Student,通过构造函数创建了对象s1const s1 = new Student()),也就是我们经常说的s1是构造函数Student实例

0a531da356cd1b4a80130d004f8de3d.png

此时构造函数Student和实例对象s1的原型都指向Student的原型对象,只是叫法不一样,构造函数上指向原型对象的地址名叫做prototype,实例对象s1指向原型对象的地址名叫做__proto__,这些属性名其实在我们日常开发时经常会见到。同时原型对象中的constructor又指向构造函数Student

整体构成了构造函数的三角关系,那么原型链是什么呢,还要继续往上走,我们可以清楚的看到,即便是原型对象,它始终还是一个对象,它也有自己的__proto__属性(所有对象都有__proto__这个属性,什么是对象?typeof 变量/常量 === 'object'),如下图所示。

cbcdbd96decc17fec7bd42def46f71b.png

Student的原型对象的__proto__属性,指向了Object的原型对象,这就是为什么你平时创建的对象字面量,或者是生成的实例对象可以使用Object上所有方法的原因(这个原因我们最后赘述)
同时我们反推可以知道,Object原型对象一定是Object构造函数的prototype

以下这块内容不太容易看懂的话可以多品味 构造函数 -> 实例对象 -> 原型对象,这个单层的三角关系
这时候我们会不太理解为什么Object构造函数为什么指向了Student的原型对象,是因为所有的对象都是通过构造函数生成的,所以在创建构造函数Student时,Object构造函数就同时成了一个原型对象,这个原型对象被地址名为Student的构造函数所引用,同时与s1也发生了关联。

当我们继续顺着Object原型对象再往上找__proto__时,你会发现,Object原型对象的__proto__null,如下图

4a9c62b2170cb43390b81705fc58472.png

有兴趣的话,大家可以一层一层的找找看。

那么我们常说的原型链其实就是图中右侧所有被__proto__关联起来的一条链,这个链就是原型链

这其中还包含着继承的概念,继承的概念在本文不再赘述。

我们最后再说为什么我们自己创建的所有对象,都可以使用Object原型上的所有方法,是因为实例对象使用的所有方法,都会顺着原型链一层一层往上去寻找,知道找到第一个匹配的方法,否则就会报错。这也是我们需要了解原型链的意义之一,同时我们还可以利用原型链这个特点,找到更多自定义的方法来解决我们实际开发中的问题。


_香蕉大神
98 声望1 粉丝

努力变强(tu)?!