javascript-inherit-conclusion

This article was wrote in Chinese. Javascript inherit’s simple conclusion

Object 继承

最简单的继承就是

1
2
3
4
5
6
7
8
9
function SuperType(){
this.supValue = true;
}

function SubTupe(){
this.subValue = false;
}

SubType.prototype = new SuerType();

但是这种继承但来的问题就是如果有引用类型的值,那么就会共享

1
2
3
4
5
6
7
8
9
10
11
12
13
function SuperType(){
this.colors = ['red','black'];
}

function SubType(){

}

SubType.prototype = new SuperType();
var sub1 = new SubType();
sub1.color.push('white');
var sub2 = new SubType();
sub2.colors; // ['red','black','white'];

为了解决这种问题有一种方法叫做借用构造函数

借用构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
function SuperType(){
this.colors = ['red','black'];
}

function SubType(){
SuperType.call(this);
}

var instance1 = new SubType();
var sub1 = new SubType();
sub1.color.push('white');
var sub2 = new SubType();
sub2.colors; // ['red','black'];

借用构造函数有一个优势就是可以在子类型构造函数中向超类型构造函数传递参数
借用构造函数的问题就是方法都在构造函数中定义,函数复用无从谈起
所以出现了另外一种继承方式组合继承

组合继承

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function SuperType(name){
this.name = name;
this.colors = ["red","blue"];
}

SuperType.prototype.sayName = function(){
alert(this.name);
}

function SubType(name,age){
Super.call(this,name);
this.age = age;
}

SubType.prototype = new SuperType();

SubType.prototype.sayAge = function(){
alert(this.age);
}

var instance1 = new SubType('Yi',29);
instance1.colors.push('black');

原型式继承

1
2
3
4
5
function object(o){
function F(){}
F.prototype = o;
return new F();
}

本质上讲object()对传入的对象进行了一次浅复制
Object.create()规范了原型式继承
Object.create()接受两个参数,一个用作新对象原型的对象,和一个可选的为新对象定义额外属性的对象,在传入一个参数的情况下 Object.create()与object()方法行为相同

1
2
3
4
5
6
7
8
9
10
11
var person = {
name: "Yi"
}

var anotherPerson = Object.create(person,{
name:{
value: 'hi'
}
});

anotherPerson.name; // 'hi'

包含引用类型值得属性,始终都会共享相应的值,就像使用原型模式一样

寄生式继承

1
2
3
4
5
6
7
function createAnother(obj){
var clone = object(obj);
clone.sayName = function(){
alert(this.name);
}
return clone;
}

包含引用类型值得属性,始终都会共享相应的值,就像使用原型模式一样

寄生组合式继承

组合式继承的不足就是会调用两次超类型的构造函数
一次是在创建子类型原型的时候,另一次是在子类型构造函数内部。
本质是不必为了子类指定原型而调用超类型的构造函数。

1
2
3
4
5
function inheritPrototype(subType,superType){
var prototype = object(superType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
}