借用构造函数:在子类型构造函数的内部调用超类型构造函数.
function Father(){
this.shoe = ["aj1*off","aj1*ts","aj4*kaws"];
}
function Son(){
Father.call(this); //继承了Father的全部,且向父类型传递参数
}
var instance1 = new Father();
instance1.shoe.pop("aj1*off");
console.log(instance1.shoe); //["aj1*ts","aj4*kaws"]
var instance2 = new Son();
console.log(instance2.shoe); //["aj1*off","aj1*ts","aj4*kaws"] 可见引用类型值是独立的
随之而来的是, 如果仅仅借用构造函数,那么将无法避免构造函数模式存在的问题–方法都在构造函数中定义, 因此函数复用也就不可用了.而且超类型(如Father)中定义的方法,对子类型而言也是不可见的. 考虑此,借用构造函数的技术也很少单独使用.
组合继承 :在借用构造函数继承中弥补了他的缺点:使用原型链实现对原型属性和方法的继承
function Father(name){
this.name = name;
this.shoe = ["aj1*off","aj1*ts","aj4*kaws"];
}
Father.prototype.sayName = function(){
alert(this.name);
};
function Son(name,age){
Father.call(this,name); //继承实例属性,第一次调用Father()
this.age = age;
}
Son.prototype = new Father(); //继承父类方法,第二次调用Father()
Son.prototype.sayAge = function(){
alert(this.age);
}
var instance1 = new Son("Aimlessly",1);
instance1.shoe.push("aj6");
console.log(instance1.shoe); //["aj1*off","aj1*ts","aj4*kaws","aj6"]
instance1.sayName(); //Aimlessly
instance1.sayAge(); //2
这种继承的优点是可以对实例属性和原型属性和方法的继承,但是两次父类构造函数, 造成了不必要的消耗
原型继承:先创建一个临时性的构造函数, 然后将传入的对象作为这个构造函数的原型,最后返回了这个临时类型的一个新实例.
- 在 ECMAScript5 中,通过新增 object.create() 方法规范
- object.create() 接收两个参数:
- 一个用作新对象原型的对象
- (可选的)一个为新对象定义额外属性的对象
var shoeBox = {
shoe : ["aj1*off","aj1*ts","aj4*kaws"]
};
var anotherShoeBox = Object.create(shoeBox);
anotherShoeBox.shoe.push("yeezy350");
alert(person.shoes); //["aj1*off","aj1*ts","aj4*kaws","yeezy350"]
不能够复用,而且由于ES5中提出所以有兼容问题
寄生式继承:创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后再像真的是它做了所有工作一样返回对象(类似工程模和构造函数)
function createAnother(original){
var clone = object(original); //通过调用object函数创建一个新对象
clone.sayHi = function(){ //以某种方式来增强这个对象
alert("hi");
};
return clone; //返回这个对象
}
不能够复用
寄生组合式继承:和名字一样是寄生组合时继承的融合
function extend(subClass, superClass) {
var F = function() {};
F.prototype = superClass.prototype;
subClass.prototype = new F();
subClass.prototype.constructor = subClass;
subClass.superclass = superClass.prototype;
if(superClass.prototype.constructor == Object.prototype.constructor) {
superClass.prototype.constructor = superClass;
}
}