原型和原型链的相关知识

89 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的第4天

这里很大部分知识来自于 juejin.cn/post/684490… 这位大佬的思路!

比较关键的先导知识

__proto__和constructor属性是对象所独有的;② prototype属性是函数所独有的。但是由于JS中函数也是一种对象,所以函数也拥有proto和constructor属性。

关于prototype

根据先导知识的所记的东西,prototype是函数所独有的,我们用函数构造出的实例它本身是不包含prototype这个对象的。这里我所说的函数是需要明确声明的那种函数例如:Person(){}。这样的声明才会有prototype。那么这个prototype是什么?在中文的翻译中,prototype叫做“原型”。prototype的意义就是:在这里面存储一些共享属性和方法,这些方法是通用的。当有实例以此函数为构造函数创造出实例,这个实例就可以根据__proto__这个纽带来连接这个prototype。使用里面的属性和方法。

关于constructor

接着我们说说构造函数。构造函数的意义就是:构造“我”(我是一个实例)的那个函数就是构造函数。如果给我们一个例子 let person1 = new Person(); 此时person1就是实例,对于Person就是person1的构造函数。构造函数的英语就是constructor。也就是上面提到的对象独有的属性。但是我们该如何从实例查询到自己的构造函数呢?例如,对于person1这个实例,我们很清楚它的构造函数是Person,那这个信息是怎么找到的?我们可以根据如下代码进行查看:person1.__proto__.constructor。这样可以清楚的看到我们person的构造函数就是Person。

关于__proto__

为了解决这个问题,我们需要清楚的知道__proto__代表的是什么。根据在网上可以知道__proto__的意义是:让实例能找到自己的原型对象。所以__proto__的链接的就是构造函数的prototype。还拿上面的例子来说明:Person和person1,对于person1.__proto__ 它所指向的就是Person.prototype。所以person1.__proto__===Person.prototype。它们指向的是同一个地址,是完全相等的。这就是__proto__的实际意义。当然,对于Person它也是有__proto__的,它的指向是Function.prototype。

所以对于上面person1.__proto__.constructor它其实也等于Person.prototype.constructor等于是Person()。所以我们找到了我们的构造函数!而对于Person.prototype的构造函数,可以根据Person.__proto__.constructor查询,最后结果为Function。对于Function,它是所有函数的构造函数,可以理解为它是所有函数的爹。因为它所以js中的函数也是对象。Function的构造函数就是自己Function.prototype.constructor === Function

关于原型链

原型链也就是将原型对象像羊肉串一样串起来成为一条链,好粗暴的解释,但的确很形象。原型对象也就是prototype。也就是说,原型链是将所有函数的prototype对象连接在一起。因为prototype也是一个对象。所以prototype也是有__proto__。它指向的是创建当前prototype的构造函数的prototype。对于prototype的根源是object的prototype。所有函数的prototype都是object的实例

因为这里有的地方有些抽象,拿文字描述的话效果不好,这里借用一下前辈的图片。

可以看到所有的prototype的__proto__最终都指向object.prototype。而object.prototype最终指向了null。形成一个完整的链路。

**左边的图:**Function函数因为是个特殊的例子,它的构造函数就是自己,所以__proto__属性也指向自己的prototype对象;但它的特殊性并不影响它的prototype对象依然不出意外的是Object函数的实例

右边的图:这个理解起来就很难受,因为Object函数和别的函数一样也是Function函数的实例,所以它的proto属性毫无例外地是指向Function函数的prototype对象,但是问题是Function函数中的prototype本身又是Object函数的实例对象,所以Function函数中的prototype对象中的proto属性就指向Object函数的prototype对象,这就形成“我中有你,你中有我”的情况,也是造成难以理解的原因之一

原型链引出新的继承方式

这里直接看大佬的博客把,它总结的非常好!