最近在项目中经常遇到,且与同事经常探讨关于js原型链的知识。发现其实很多工作经验好多年的同事也记不太清楚原型链的整个环节,今天在这里专门的把链图画出来,并且加以讲解,希望能够帮到更多前端的朋友。
原型链其实就是一个三角关系,如下图所示,我们编写了一个构造函数Student
,通过构造函数创建了对象s1
(const s1 = new Student()
),也就是我们经常说的s1
是构造函数Student
的实例
。
此时构造函数Student
和实例对象s1
的原型都指向Student
的原型对象,只是叫法不一样,构造函数上指向原型对象的地址名叫做prototype
,实例对象s1
指向原型对象的地址名叫做__proto__
,这些属性名其实在我们日常开发时经常会见到。同时原型对象中的constructor
又指向构造函数Student
。
整体构成了构造函数的三角关系
,那么原型链是什么呢,还要继续往上走,我们可以清楚的看到,即便是原型对象,它始终还是一个对象
,它也有自己的__proto__
属性(所有对象都有__proto__
这个属性,什么是对象?typeof 变量/常量 === 'object'
),如下图所示。
Student
的原型对象的__proto__
属性,指向了Object
的原型对象,这就是为什么你平时创建的对象字面量
,或者是生成的实例对象可以使用Object
上所有方法的原因(这个原因我们最后赘述)
同时我们反推可以知道,Object
原型对象一定是Object
构造函数的prototype
。
以下这块内容不太容易看懂的话可以多品味 构造函数 -> 实例对象 -> 原型对象,这个单层的三角关系
这时候我们会不太理解为什么Object
构造函数为什么指向了Student
的原型对象,是因为所有的对象都是通过构造函数生成的,所以在创建构造函数Student
时,Object
构造函数就同时成了一个原型对象,这个原型对象被地址名为Student
的构造函数所引用,同时与s1
也发生了关联。
当我们继续顺着Object
原型对象再往上找__proto__
时,你会发现,Object
原型对象的__proto__
是null
,如下图
有兴趣的话,大家可以一层一层的找找看。
那么我们常说的原型链
其实就是图中右侧所有被__proto__
关联起来的一条链,这个链就是原型链
。
这其中还包含着继承
的概念,继承
的概念在本文不再赘述。
我们最后再说为什么我们自己创建的所有对象,都可以使用Object
原型上的所有方法,是因为实例对象使用的所有方法,都会顺着原型链一层一层往上去寻找,知道找到第一个
匹配的方法,否则就会报错。这也是我们需要了解原型链的意义之一,同时我们还可以利用原型链这个特点,找到更多自定义的方法来解决我们实际开发中的问题。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net