聊聊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.prototype和Object.prototype是两个特殊的对象,他们由引擎来创建- 除了以上两个特殊对象,其他对象都是通过构造器
new出来的 - 函数的 属性
prototype指向一个对象,这个对象就是原型 - 对象的
__proto__指向它构造函数的原型,__proto__将对象和构造函数的原型连接起来组成了原型链

浙公网安备 33010602011771号