文章参考资料在这里
_proto_
_proto_是js中所有对象都拥有的一个属性,它就是我们提到的原型链的组成部分。当访问一个对象的属性或者方法的时候,如果在对象自身没有找到就会去该对象的_proto_上寻找,一层一层的找下去。
prototype
prototype是只有函数才有的属性。它也是一个对象,当你用new来创建一个实例的时候prototype就被用来构造出_proto_
下面用一张图来表明他们之间的关系。
1-1
乍一看有点乱,我们一点一点的看。
首先我们申明了一个名为Foo的方法,同时给Foo的prototype添加了两个属性。
function Foo (i) {
this.y = i;
}
Foo.prototype.x = 10;
Foo.prototype.calculate = function () {};复制代码
申明了Foo之后我们通过new来创建出两个实例b 和 c
var b = new Foo(20);
var c = new Foo(30);复制代码
在浏览器的控制台输出b和c会发现他们包含y和_proto_属性,如下图所示。
1-2
这时候我们去访问b实例的y属性很明显会返回20,但是这是去访问实例上没有的属性x和方法calculate时也能返回对应的值。这时候b的_proto_就起作用了。当访问一个实例上没有的属性时他就回去自己的_proto_上寻找。如上所说_proto_是实例创建出来时通过prototype构造的。我们之前给Foo的prototype赋过值,所以能访问到。正如图1-1所示,实例b的_proto_指向的是Foo的prototype。比较这两个值你会发现 b.__proto__ === Foo.prototype 返回true。
在看图1-1,Foo的_proto_指向了Function.prototype,Foo是个function,所以它的_proto_指向Funtion的prototype。和一开头提到的那样prototype也是js对象,所以它也有自己_proto_属性。这个_proto_指向这个链的最底端Object的prototype,就这样一层一层形成一个链,Object的prototype除了一些自带的方法和属性也有_proto_属性,但是为null,所以在访问属性的时候如果到了这一层还没找到就会返回undefined。
例子里面的是通过new关键字创建出来的Foo的实例,那假如是我们直接申明的js对象呢?那就更简单了,它会直接指向Object.prototype。
var obj = { name: 'jack' };
obj._proto_ === Object.prptotype // true复制代码
关于prototype和_proto_的关系就到这里,假如本文有什么错误,还望各位看官指出。