对JavaScript原型链结构和作用的简单分析

发布时间 2023-03-23 00:44:14作者: 许小仙

 

首先是分析一下主要零件(对象,函数对象),再分析他们的连接方式。就可以很直观的理解原型链了。

 

一、对象

 

  1. 每个对象都有一个constructor属性; 指向其构造函数。
  2. 还有一个__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共享。