四张图带你搞定原型和原型链
在讲原型和原型链之前,先铺垫一些前置知识:
所有的对象都是通过
new 函数
生成的。 包括let obj = {}
,这种形式其实是语法糖
,本质上是通过let obj = new Object()
生成的。那么函数又是如何生成的呢?从图中可以清晰的看出函数
本质上是通过new Function
生成的,尽管我们平时不会这么去写,当然也不建议这么去写
所有的函数也都是对象,既然是对象,那么函数一定会有属性。 比如:
Array.form
、Array.isArray
等等对象是一种引用类型。
🍇 原型 prototype
所有的函数都有一个属性:prototype
,称之为函数原型
。函数创建之初就会自动加上prototype
属性。
那什么是原型呢?
默认情况下,prototype
就是一个普通的 object 对象。
默认情况下,prototype 中有一个属性:constructor
,它也是一个对象,它指向构造函数本身。
这张图很清晰说明了prototype
和constructor
之间的关系,每个函数(add、Object、Array、nothing)都有一个属性prototype
,它指向函数的原型,而函数的原型中也有一个属性constructor
,它也是一个对象,constructor
指向构造函数本身。
那原型有什么用呢?原型本身没什么用,但是配合隐式原型却大有作为
🍄 隐式原型 __proto__
所有的对象都有一个属性:__proto__
,称之为隐式原型。 前后两个下划线表示系统私有属性,不要轻易动它。
默认情况下,隐式原型指向创建该对象的函数的原型。这句话特别重要,它将隐式原型跟原型联系起来了,那什么意思呢?
举个栗子🌰:
举个栗子🌰:
现在我们知道隐式原型指向谁,然后我们将prototype
、constructor
、__proto__
三者关系绘图如下:
在前置知识中,已经说过所有的对象都是通过new 函数
进行创建的,便有了上图关系。细心的小伙伴应该已经发现对象 1 的__proto__
、对象 2 的__proto__
以及函数 add 的prototype
三者指向同一块内存空间,这也就解释了为什么要把函数写在原型上,这是因为将函数写在原型上,只要是通过 add 构造函数创建的对象都可以访问这个函数。
访问对象成员的顺序是:首先会看当前对象中是否存在该属性或者方法,若存在,就直接使用了,否则继续顺着原型链依次查找。
MDN 文档中一段话:
之所以会继承Array.prototype
就是因为隐式原型
的存在,这也是提示我们,将来要把对象需要共享的东西写在原型上,特别是函数,这种行为有个比较有意思的名称,叫猴子补丁
,也许是因为🐒善于模仿,在原型中加入成员,以增强对象的功能,但也是有弊端的,会造成原型污染,所以还是谨慎使用。
🍓 原型链
这张图搞清楚后,自然明白何为原型链,我们一起过一遍
我们先看
白色线条
,白色线条表示原型,在原型部分我们已经说了,所有的函数都有一个属性prototype
,那么Object函数
的原型指向Object原型
,同理,我们自定义函数
的原型必然指向自定义函数原型
,这里有个比较特殊的点,就是Function函数
,没有任何东西创建它,它是由 JS 引擎启动的时候直接添加到内存里面的,故Function函数
直接指向Function原型
。再看
绿色线条
,绿色线条表示new
,读到这里,想必大家都知道所有的函数都是通过new Function()
创建的,所以Function函数
分别指向Object
和自定义函数
无可厚非,图中有一条线是自定义函数
指向自定义对象
,文章开头已经说了,所有的对象都是通过new 函数
进行创建的,代码表示:
最后再看
蓝色线条
,蓝色线条表示隐式原型,我在隐式原型那部分也已经说了,所有的对象都有一条属性__proto__
,那函数是对象吧,那隐式原型指向谁呢?隐式原型指向创建该对象的函数的原型,要理解这句话,我们必须要知道函数是谁创建的?这个谁的原型是什么?所有的函数都是Function函数创建的
,Function函数
的原型指向Function原型
,这是个特殊点,故Object函数
和自定义函数
的隐式原型指向Function原型
,Function函数
也是函数,由于没有谁创建它,是被直接添加到内存的,它的原型是指向Function原型
,这同样是一个特殊点。
自测题一道:大家可以试着做一下,然后可以根据最后一张图进行检查
😊 好了, 以上就是我的分享,小伙伴们点个赞再走吧 👍 支持一下哦~ 😘,我会更有动力的 🤞
版权声明: 本文为 InfoQ 作者【法医】的原创文章。
原文链接:【http://xie.infoq.cn/article/07674dd67268f61f724986423】。文章转载请联系作者。
评论