对JavaScript原型链结构和作用的简单分析
首先是分析一下主要零件(对象,函数对象),再分析他们的连接方式。就可以很直观的理解原型链了。
一、对象
- 每个对象都有一个constructor属性; 指向其构造函数。
- 还有一个__proto__属性 ; 指向其构造函数的原型对象。
因此一个普通对象大概长这个样子
二、函数对象
函数对象也是对象,因此constructor和__proto__都有,但是函数对象还会创建一个原型对象,并通过prototype指向它
三、链条结构
在清楚零件的结构后,就需要来拼接他们了。MDN的描述如下:
我们知道JS对象几乎都是Object的实例,而函数则都是Function的实例。
函数也是对象,因此根据上面前半句,我们可以知道Function是Object的实例。
有趣的是Object也是函数,根据后半句,可以得Object是Function的实例。
那么谁应该在原型链的最前端,就是个鸡和蛋问题。
网上经常出现的关系图如下:
这张图是正确的,但可能不够直观。我选择代入前面画的零件:
看上图,其实就是Object和它的原型object,都没有将__proto__指向其构造函数Function的原型对象function。于是可以将Object放在链条前端。
上面的操作会令很多人迷惑,但是事实就是如此。
四、原型的作用
JS的继承是基于原型链实现的。
当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。
从上面的分析可以知道,函数对象拥有原型对象,使用该函数new出来的普通对象,通过__proto__指向该原型对象,假如我们有自定义函数func(),并new了f1,f2.
那么f1.num和f1.number都是可以访问到的,关键在于num是独享的,而number还要和f2共享。
本文来自博客园,作者:许小仙,转载请注明原文链接:https://www.cnblogs.com/ovins/p/17246008.html