借用构造函数
这是经典的继承方式。
栗子:
function Father() {
this.colors = ["red","green","blue"];
}
function Son() {
Father.call(this);
}
var instance1 = new Son();
alert( Father.prototype.isPrototypeOf(instance1)) //false
instance1.colors.push("black");
console.log(instance1.colors); //"red","green","blue","black"
var instance2 = new Son();
console.log(instance2.colors); //"red","green","blue" 可见引用类型值是独立的
只是借用了Father构造函数,但并没有改变_proto_指针的指向,Father函数并不在instance1的原型链上。
这个继承方法解决了两个问题:
- 保证了引用类型属性值是独立的,不再被所有实例共享;
- 子类型创建时也能向父类传递参数。
组合继承
上一种方法只是调用了Father构造函数,但是没办法调用Father.prototype上的方法。
组合继承将原型链和借用构造函数继承结合在一起,既能借用构造函数,也能继承原型链上的方法。
栗子:
function Father1(name) { //使用借用构造函数方法继承
this.colors = ["red","green","blue"];
this.name = name;
}
Father1.prototype.sayName = function() { //借用原型链继承此方法
alert(this.name);
};
function Son1(name,age) {
Father1.call(this,name);
this.age = age;
}
Son1.prototype = new Father1();
Son1.prototype.sayAge = function() {
alert(this.age);
};
var instance3 = new Son1("peter",15);
instance3.colors.push("black");
console.log(instance3.colors) //"red","green","blue","black"
instance3.sayName(); //"peter"
instance3.sayAge(); //15
var instance4 = new Son("liHua",20);
console.log(instance4.colors); //"red","green","blue"
instance3.sayName(); //"liHua"
instance3.sayAge(); //20
这是Javascript最常用的继承方式,而且, instanceof 和 isPrototypeOf( )也能用于识别基于组合继承创建的对象.
原型继承
var person = {
name : ["liHua","wangHua","baiXue"]
};
var anotherPerson = Object.create(person);
anotherPerson.name.push("huTai");
console.log(anotherPerson.name); //"liHua","wangHua","baiXue","huTai"
console.log(person.name); //"liHua","wangHua","baiXue","huTai"
将person对象传入Object函数中,得到一个新对象,这个新对象以person为原型,则原型中包含的引用类型值属性被共享了,既person.name不仅被person所有,而且也被anotherPerson共享。
寄生式继承
创建一个仅用于封装继承过程的函数,该函数在内部以某种方式来增强对象,最后返回被增强的对象。
var clonePerson = function(original) {
var clone = Object(original); //通过Object函数创建一个以接收对象为原型的新对象
clone.sayHi = function() { //增强这个对象
alert("Hi");
};
return clone; //返回对象
};
寄生组合式继承
基本思路: 不必为了指定子类型的原型而调用超类型的构造函数
function extend(subClass,superClass){
var prototype = object(superClass.prototype);//创建对象
prototype.constructor = subClass;//增强对象
subClass.prototype = prototype;//指定对象
}
下面我们来看下extend的另一种更为有效的扩展.
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;
}
}
补充
这篇笔记里用到的栗子出自这里。