原型链就是 实例对象 与 原型 之间的连接。
function Foo(name){ this.name=name; } Foo.prototype.num=10; var a=new Foo(); alert(a.num); //10
上面代码中,先创建了一个构造函数 Foo(),并且在构造函数的原型上添加一个 num 属性,最后创建实例 a ,在 a 上取到 num 属性,等于10。
我们稍微分析下,num属性是添加在Foo.prototype上的,为什么a.num可以取到?这就是原型链的功劳。
原型中有一条规则,当试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么会去它的__proto__中寻找。
__proto__是隐式原型,还有一条规则是,所有的引用类型(数组,对象,函数),__proto__属性值指向它的构造函数的 prototype 属性值。
根据这两条规则,可以得出一个结论就是 a.__proto__===Foo.prototype,可以验证下:
现在就很容易懂上面代码的执行过程了,a对象本身没有num属性,那么就会去它的__proto__中查找,即去它的构造函数中的prototype查找,并找到num属性。
这就是原型添加属性和方法的过程,是通过原型链连接的。
需要注意的是,在对象中查找属性时,是先从自身查找的,所以本身的属性优先级最高,如下:
function Foo(name){ this.name=name; this.num=5; } Foo.prototype.num=10; var a=new Foo(); alert(a.num); //5
我在构造函数中,添加了num属性,值为5,它的原型中也有num属性,值为10,最后得到的结果是5。
这就好比是CSS中,style中样式优先级高于样式表中样式。