每个人遇到这个问题,可能有不同的回答,但是回答的中心应该都是要首先简单阐述下什么是原型链(套娃链?), 然后就可以开始讲讲他继承的具体实现了。
什么是原型链呢
首先我们回顾一下 构造函数 , 原型对象 , 实例 三者的关系。
我们知道 每个构造函数 都有一个 原型对象
每个原型对象都有一个 constructor 指针指向构造函数
每个原型都有一个 __proto__ 只想原型对象
假如我们让原型对象等于另一个类型的实例 ,那么此时原型对象的 __proto__指针将指向这个类型的原型对象
再假如这个类型(a)的原型对象又是另一个类型(b)的原型对象,那么此时a中的__proto__指针将只想b的原型对象
如此层层替进,就构成了示例与原型的链条,这就是原型链的基本概念
实现原型链的基本方式
```
function Super () {
this.Supervalue = true;
}
Super.prototype.getSupervalue = function(){
return this.Supervalue;
}
function Subtype () {
this.Subvalue = false;
}
Subtype.prototype = new Super();
Subtype.prototype.getSubvalue = function () {
return this.Subvalue
}
var ins = new Subtype();
alert(ins.getSupervalue()); //true
在这里定义了一个Super构造函数,通过创建Super实例,并将该实例赋给Subtype.prototype实现,本质就是重写原型对象
然后我们通过Subtype实例化了一个ins,通过这个对象调用Super的getSupervalue方法,最终返回true就是通过原型链实现的,
然后可能有同学想到了一个问题,Super的原型对象是谁呢?他也没有重写原型对象啊。
其实,所有函数的初始原型对象都是一个Object实例,这也正是我们能使用toString 等方法的原因
```
原型与实例的关系
instanceof 操作符
alert(ins instanceof Subtype); //true
alert(ins instanceof Super); //true
alert(ins instanceof Object); //true
只要在ins的原型链上出现过的构造函数,都会返回true
那么也可以说 ins 是他们三个的实例
isPrototypeof
只要是原型链中出现过的原型,都可以说是该原型链所派生的实例的原型
alert(Object.prototype.isPrototypeof(ins)) //true;
小心的定义原型方法嗷
通过原型链实现继承时,不能使用对象字面量创建原型方法,因为这样会重写对象原型链
原型链的问题
原型链用来继承也会有一些问题,最主要的来自引用类型值得原型。再通过原型来实现继承的时候,原型实际上会变成另一个类型的实例,实例属性自然也就变成了原型属性,那么相对于引用类型的属性来说,其某一实例修改引用类型的值,所有实例都会变化