js中的继承

js中的继承与其他强类型语言有所不同

利用原型链

将原型链指向另外一个类型的实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function SuperType() {
this.property = true;
}
SuperType.prototype.getSuperValue = function() {
return this.property;
}

function SubType() {
this.subProperty = false;
}
//继承superProperty
SubType.prototype = new SuperType();

SubType.prototype.getSubValue = function() {
return this.subProperty;
}
var instance = new SubType();
console.log(instance.getSuperValue());

上述继承主要方式是通过创建SuperType实例,实现的本质是通过重写原型对象。
注意此时instance的constrctor是指向SuperType的,因为被重写了
注意问题:在通过原型链继承时,原来的实例属性就变成了原型属性,原型属性若是引用类型则会出现共享问题,改变一个就会引起其他的也改变.
colors会在子类中全部共享。

1
2
3
function SuperType() {
this.colors = [1,2,3];
}

借用构造函数

使用apply和call,相当于子类有了自己的属性,和在父类中同名。

1
2
3
4
5
6
function SuperType() {
this.colors = [1,2,3];
}
function SubType() {
SuperType.call(this);
} 也可以像call中传递参数

使用组合继承

1
2
3
4
5
6
7
8
9
10
11
12
13
function SuperType(){
this.property = true;
this.colors = [1,2,3];
}
SuperType.prototype.getValue = function() {
return this.colors;
}
function SubType() {
this.name = "ckq";
SuperType.call(this);
}
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;

利用组合继承,将父类中的所有属性都可以拿到子类中。然后通过修改原型链的方式,指向父类的实例,但是要注意,要修改constructor,是他指向自己,不指向父类。

寄生式继承

思路,创建一个封装继承过程的函数,通过将原有对象克隆下来到新的对象,在新的对象上添加新的方法

1
2
3
4
5
6
function createAnother(orignial){
var clone = object(orignial);
clone.sayHi = function() {
alert('hi');
}
}

寄生式组合继承

组合继承的毛病,无论在什么情况下,都会2次调用构造函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function inhertProperty(SubType,SuperType){
var prototype = Object(SuperType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
}
//将父类拷贝下来,副本的constructor修改,subType的prototype指向新的prototype.
function SuperType(name){
this.name = "ckq";
this.colors = [1,2,3];
}
function SubType(name,age){
SuperType.call(this,name);

}
inhertProperty(SubType,SuperType);