JS中的_proto_和prototype
对象的内部原型__proto__和构造器的原型prototype:
每个对象都有__proto__属性来标识自己所继承的原型
但是只有函数才有prototype属性(ES规范就这么定的)。
因为JS没有类因此通过函数来模拟类。当你创建函数时,JS会为这个函数自动添加prototype属性,prototype的值是一个有 constructor 属性的对象,切记不是空对象。而当这个函数被作为构造函数调用(即通过new来创建一个实例)时,JS会帮你创建该构造函数的实例(例如var d=new Peple(), 此时Dog()函数被作为构造函数创建了一个实例,而JS会帮你完成new Peple()的过程),实例继承了构造函数的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而产生。