JS中的_proto_和prototype
对象的内部原型__proto__
和构造器的原型prototype
:
每个对象都有__proto__
属性来标识自己所继承的原型
但是只有函数才有prototype
属性(ES规范就这么定的)。
因为JS没有类因此通过函数来模拟类。当你创建函数时,JS会为这个函数自动添加prototype
属性,prototype
的值是一个有 constructor 属性的对象,切记不是空对象。而当这个函数被作为构造函数调用(即通过new来创建一个实例)时,JS会帮你创建该构造函数的实例(例如var d=new People(), 此时People()函数被作为构造函数创建了一个实例,而JS会帮你完成new People()的过程),实例继承了构造函数的prototype
(其实是生成了指向其构造函数的prototype
的指针_proto_
)
上图中首先创建了一个构造函数People然后创建了实例p,打印出实例p的结果如下图所示
打印出People.prototype
的结果如下图所示
可以发现实例p的_proto_
是指向constructor 的prototype
,意思就是实例p的内部原型指向的就是它的构造函数People的原型。
再讲一下Function和Object的关系
上图可以首先清晰的看到Function.prototype.__proto__===Object.prototype
,
Object.prototype.__proto__ === null
,说明Object.prototype
是原型链顶端
最后,借用一下https://github.com/creeperyang/blog/issues/9,说明比较难理解的两点:
一 .Function.prototype
是个不同于一般函数(对象)的函数(对象)。
Function.prototype
像普通函数一样可以调用,但总是返回undefined
。- 普通函数实际上是
Function
的实例,即普通函数继承于Function.prototype。func.__proto__ ===Function.prototype
。 Function.prototype
继承于Object.prototype
,并且没有prototype
这个属性。func.prototype
是普通对象,Function.prototype.prototype
是null
。- 所以,
Function.prototype
其实是个另类的函数,可以独立于/先于Function
产生。
二 .Object
本身是个(构造)函数,是Function
的实例,即Object.__proto__
就是Function.prototype
。Object
和Function.prototype
这实际上就是鸡和蛋的问题
最后总结:先有Object.prototype
(原型链顶端),Function.prototype
继承Object.prototype
而产生,最后,Function
和Object
和其它构造函数继承Function.prototype
而产生。