继承:
//父类构造函数
function Father(name){
this.name = name;
this.sum = function(){
console.log(this.name);
}
}
Father.prototype.age = 30;
1 原型链 :子构造函数的原型等于父类的实例
// 1.原型链继承
function Son(){
this.name = 'son';
}
Son.prototype = new Father();
var son = new Son();//实例的原型等于父类的实例
特点:1.新实例会继承的属性有:构造函数的属性,父类构造函数的属性,父类原型的属性
2.不会继承父类实例的属性
3.新实例无法向父类构造函数传参
缺点:1.原型上的属性是共享的,当一个实例修改了原型属性,另一个属性的原型也会被修改
2.过多的继承了没用的属性
2.借用构造函数继承:用call和apply将父类构造函数引到子类函数中去
function Son(){
Father.call(this,'son');
this.age = 10;
}
var son = new Son();
console.log(son.name ,son.age)//son 10
console.log(son instanceof Father) //false
特点:1.只继承了父类构造函数的属性,没有继承父类原型的属性
2.可以继承多个构造函数的属性
3.在子实例中可以向父类实例传参
缺点:1.只继承了父类构造函数的属性
2.每次构造函数都要多走一个函数,浪费效率,没有达到函数复用的效果
3. 组合继承:原型链+借用构造函数
思路:使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承。
function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){ alert(this.name)};
function SubType(name, age){
//继承属性
SuperType.call(this, name);
this.age = age;
}
//继承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){alert(this.age)};
var instance1 = new SubType("Nicholas", 29);
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29
var instance2 = new SubType("Greg", 27);
alert(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27
特点:避免了原型链和借用构造函数的缺陷,是JavaScript中最常用的继承模式。而且instanceof和isPrototypeOf也能够用于识别基于组合继承创建的对象。
4.共享原型:Son.prototype = Father.prototype, Son和Father共享原型
function Father(){}
function Son(){}
Father.prototype.name = 'fatherProto';
Son.prototype = Father.prototype;
var son = new Son();
var father = new Father();
console.log(son.name,father.name);//fatherProto fatherProto
缺点:不能随便改变原型,因为两个实例公用一个原型
5.圣杯模式: 方法3的改进,另外加个构造函数function F(){}当做中间层,然后让F和
Father共有一个原型:F.prototype = Father.prototype,然后使用原型链继承模式形成继承关系:Son.prototype = new F();,现在改变Son.prototype就不会影响Father.prototype.
function myinherit(Son,Father){
function F(){}
F.prototype = Father.prototype;
Son.prototype = new F();
Son.prototype.constructor = Son;//如果不写这一句,constructor指向Father
Son.prototype.uber = Father.prototype;
}
function Father(){}
function Son(){}
Father.prototype.lastName = 'lhp';
myinherit(Son,Father);
var father = new Father();
var son = new Son();