聊聊javascript原型和原型链

什么是原型?

在javascript高级程序设计里面这样子解释到:

    无论什么时候,只要创建了一个新的函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。

    在默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针。

(其实这东西是javascript作者在设计这门语言的时候就没有想过继承的事情,所以就弄了这个东西来当做继承)

也就是说每个函数都有prototype这个属性,这个就是原型,是一个对象。那么既然函数也是对象,那么普通对象是不是也有这个属性

 

 但是很遗憾没有,但是对象却有__proto__,它指向对象构造函数的prototype。

 

 

也就是说原型就是函数的prototype属性,对象的__proto__属性。业界称prototype是显示原型,__proto__是隐式原型。

那你可能会疑惑那函数有__proto__属性吗?答案是肯定的,因为函数也是由new Function()创建来的。

 

那我们就肯定的说函数既有prototype属性,也有__proto__属性。普通对象只有 __proto__属性。这也很好的解释了为什么说函数也是对象的原因。

其实我很好奇原型链的终点在哪里?上面我们只知道prototype指向一个原型对象,那么这个原型对象的__proto__又指向谁?是谁构建的呢?

 指向了Object对象,那么Object又指向谁呢?

 指向了null,那么我们就大致可以认为原型链的终点是null,但是一般我们认为终点是Object

接下来我们分析下经典的原型链的图,大概就明白了:

 

 

 

从图中我们可以看到原型的大概。

但是我们需要注意的是这个地方:

 为什么是Function.__proto__ === Function.prototype?难道是Function创建了自己?以前刚刚看的时候也会犯迷糊,其实并不是自己创建了自己。

这个要从Object说起,所有的原型链都来自于Object.prototype

 

 

虽然Object.prototype是对象,但是它却不是Object创建的。而是引擎自己创建Object.prototype。

所以我们可以说:所有实例都是对象,但是对象不一定都是实例。

我们可以打印下Function.prototype:

可以看出来Function.prototype一个函数,那么函数是new Function() 出来的,Function.prototype也是new Function()的吗?显然不是,这个也是引擎自己创建的。

引擎先创建出Object.prototype,然后再创建Function.prototype,最后再利用__proto__将两者联系起来。所以这也很好的解释了。

在这里我们又可以得出一个结论所以我们又可以得出一个结论:不是所有函数都是 new Function() 产生的。

有了Function.prototype以后就产生了函数Function,也就才有了后面的new Function()得来的函数。

最后总结下:

  • Object 是所有对象的根,所有对象都可以通过 __proto__ 找到它
  • Function 是所有函数的根,所有函数都可以通过 __proto__ 找到它
  • Function.prototypeObject.prototype 是两个特殊的对象,他们由引擎来创建
  • 除了以上两个特殊对象,其他对象都是通过构造器 new 出来的
  • 函数的 属性prototype指向一个对象,这个对象就是原型
  • 对象的 __proto__ 指向它构造函数的原型, __proto__ 将对象和构造函数的原型连接起来组成了原型链
posted @ 2020-06-01 22:01  菜鸡前端  阅读(20)  评论(0)    收藏  举报