这篇博客主要是为了理清自己的思路。
先上图,所有内容都从这张图来讲。
在js中,所有的东西都是对象,包括是function。
prototype这个属性是函数特有的。有两层含义,第一层含义指的是某对象的属性,而第二层则是作为一个对象。
比如,Foo.prototype → → → Foo.prototype,它指的就是 Foo的原型属性 指向 Foo的原型对象。
proto我们可以把它叫做隐式原型,每个对象都具有该属性,它指向创建该对象的那个构造函数的原型对象。
下面开始分析图表
function Foo(){ }
Foo.prototype.a=function(){}
Foo.prototype.b=function(){}
var f1=new Foo()
在这里我们实例化Foo函数,创建了一个f1的对象,那么,f1这个对象拥有一个隐式的原型(_proto_),因为f1的构造函数(即创建f1这个实例)的函数式Foo,所以
f1的隐式原型就指向了Foo的原型对象,而Foo的原型对象是什么呢?就是我们上面说的Foo.prototype。
我们可以在Foo的原型对象上绑定很多实用的方法,如上,我们在原型对象上绑定了a,b两种方法,又由于我们的f1通过隐式原型可以访问到Foo的原型对象,因此,我们的
实例f1就可以使用绑定在Foo上面的方法了,而这种继承方式就是我们平时说的原型式继承。
我们再看,按照我们最先的说法,一切皆对象,所以function Foo()这货本身也是一个对象,既然是对象,那么也有proto这个属性吧,而它的隐式原型指向谁呢?
别急,我们慢慢来看,我们在创建函数的时候是不是有过这样的写法,
var Foo=new Function()
所以说呢,Foo的构造函数就是Function啦,那就是说我们的function Foo()这个对象它的隐式原型proto指向的就是Function.prototype了。
var o1=new Object()
按照这样的思路我们也不难发现,o1的proto指向的就是Object.prototype。
既然说到了Object.prototype,那么我们不得不理清一下Foo.prototype,Function.prototype和它的关系了。
Foo.prototype,Function.prototype分别是Foo的原型对象和Function的原型对象,这两者都是对象,既然是对象的话都有proto,
proto指向的是它的构造函数的原型对象,所以就是o1这个实例一样,它们的proto指向的就是Object.prototype。
而Object.prototype的proto就指向null了。至此整个图的关系就都出来了。
正是因为f1的proto指向Foo.prototype,而Foo.prototype的proto指向了Object.prototype,所以我们
才能够在f1这个实例上调用Object上绑定的原型方法,例如toString等。