1.继承的类型
在oo语言中,继承有两种方式,借口继承和实现继承,因为ECMAScript不支持方法签名,所以ECMAScript只支持实现继承。
2.原型链继承的实现
2.1.原型链
ES5继承可以使用原型链,原型链的形态可以理解为让一个构造函数的原型成为另一个构造函数的实例,这样会重写这个原型对象。因为有constructor,prototype的存在,使构造函数和原型有了双向确定的能力和范围延展的能力,层层延伸便构成了原型链。
function SuperType(){
this.prototype = true;
}
SuperType.prototype.getSuperValue(){
return this.prototype;
}
function SubType(){
this.subprototype = false;
}
Subtype.prototype = new SuperType();//实现继承,重写原型对象,包括constructor,现在constructor指向SuperType
var instance = new Subtype();
alert(instance.getSuperValue()); //true
当访问一个实例属性时,先搜索实例,再搜索原型对象,如果还没有找到,再向原型链继续向上搜索,在原型链的最顶端,君临着Object,所有函数的默认原型都是Object的实例。
2.2.实例与原型的关系
我们可以使用instanceof操作符或者isPrototypeOf()方法来判断原型链中是否出现过某构造函数。(判断构造函数是否在原型链上)
alert(instance instanceof Object) //true
alert(instance instanceof Supertype)//true
alert(Object.prototype.isPrototypeOf(instance));//true
alert(SuperType.prototype.isPrototypeOf(instance));//true
与使用原型模式创建对象时类似,我们使用原型链继承时,原型里面的所有属性都会被实例所共享,在创造原型链时,一个对象的原型会变成另一个对象的实例,所以这个实例的属性便会被共享。
在操作继承过来的属性时,相当于在操作原型里面的内容。这就像一个没有上锁的箱子,任何人都可以打开。并且在使用原型链继承时,我们不能向超类型的构造函数传递参数。
3.构造函数继承
3.1.借用构造函数
因为原型链继承有以上缺点,我们用其他方式来继承比较好,构造函数继承利用函数的作用域克服了原型链继承中共享的问题,但是因为方法都是写在构造函数里的,因此不能实现方法复用。
function SuperType(){
this.colors = ["red","blue","green"];
}
function SubType(){
SuperType.call(this); //在SubType作用域中运行SuperType的构造函数,实现了继承
}
var instance1 = new SubType();
instance1.colors.push("black");
alert(instance.colors);//"red, blue,green,black"
var instance2 = new SubType();
alert(instance2.colors);//"red, blue,green"
4.组合继承
在对象的创建中也出现过,我们可以结合构造函数和原型链来实现继承,构造函数实现对属性的继承,原型链实现对方法的继承,这样可以实现扬长避短的功效。
function SuperType(words){
var colors = ["red","blue","green"];
this.words = words
}
SuperType.prototype.saySometing = function(){
alert(this.words);
}
function Subtype(){
SuperType.call(this);
}
var instance1 = new SubType("hello");
var instance2 = new SubType("what?");
instance1.colors.push("black");
alert(instance1.colors);//"red,blue,green,black"
alert(instance2.colors);//"red,blue,green"
alert(instance1.saySomething());//"hello"
alert(instance2.saySomething());//"what?"
5.原型式继承
这种继承方式包含了原型链继承,用一个函数给出一个定了父类型的子类型,这个父类型由函数的参数表示。
function object(){
function F();
F.prototype = o;
return new F();
}