原型链继承
原型链的基本概念
首先理清构造函数,原型,以及实例的关系。构造函数都有一个prototype属性,指向它的原型。
同时原型又有一个contructor属性指向构造函数。通过构造函数创建的实例都有一个指针[[prototype]](在chrome等浏览器中有属性_proto_)指向
构造函数的原型。如果把原型对象等于另一个类型的实例,这样实例的原型对象中就包含了指向另一个原型对象的指针,而另外一个原型对象包含着指向构造函数
的指针,从而使用它的属性和方法,如此层层递进构成的实例与原型的链条就是原型链。
例子1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18function superType() {
this.prototype = true;
}
superType.prototype.getSuperValue = function () {
return this.prototype;
};
function SubType() {
this.subproperty = false;
}
//实现继承
SubType.prototype = new superType();
SubType.prototype.getSubValue = function () {
return this.subproperty;
};
var instance = new SubType();
console.log(instance.getSuperValue());//true
完整的原型链中还有一个所有引用类型默认继承的对象Object,toString(),valueOf()一些默认方法都来自于Object。
在上面的例子中supertype的原型对象中有一个属性[[prototype]]指向Object的原型对象,说明supertype继承与Object
确定原型和实例的关系
instanceof
instanceof操作符测试实例与原型链中出现过的函数,如果出现过则返回true
1 | alert(instance instanceof SubType);//true |
重写超类型中的方法
1 | function superType() { |
这个例子中在subtype的原型重写了getSuperValue方法,因此在subtype的实例中调用新方法,但是在supertyoe的实例中仍然会调用原来的方法
要注意的是定义方法必须在用supertype的实例替换原型后。
原型链的问题
原型属性中,如果包含引用类型的值,那这个属性会被所有实例共享。在通过原型继承时,原型事实上会变成另一个类型的实例,所以实例属性会变成现在原型的属性。
1 | function superType() { |
借用构造函数
使用call或者apply,在子类型中调用超类型的构造函数.
1 | function superType() { |
借用构造函数继承还可以传递参数1
2
3
4
5
6
7
8
9
10
11function superType(name) {
this.name = name
}
function SubType(){
superType.call(this,'phil')
this.age = 21
}
var instance = new SubType()
console.log(instance.name);//phil
console.log(instance.age);//21
组合式继承方法
组合式继承结合以上两种方法,用构造函数完成实例中属性的继承,用原型链完成原型属性方法的继承1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27function superType(name) {
this.name = name
this.colors = ['red','blue','green'];
}
superType.prototype.sayName = function () {
alert(this.name);
};
function SubType(name, age) {
superType.call(this, name);//继承属性
this.age = age
}
SubType.prototype = new superType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
alert(this.age)
}
var instance1 = new SubType('phil', 21);
instance1.colors.push('white');
alert(instance1.colors);//'red',blue,green,white'
instance1.sayName();//phil
instance1.sayAge();//age
var instance2 = new SubType('joy', 41);
alert(instance2.colors);//'red',blue,green'
instance2.sayName();//phil
instance2.sayAge();//age