继承

 
总结: 1.引用类型共享(出处:原型链继承;解决:构造函数定义属性 )
          2. 无法向超类型构造函数传递参数  (出处:原型链继承    解决:在子类型构造函数中调用超类型构造函数,并改  变this指向)
           3.方法复用 (出处:抛弃原型链继承; 解决:启用原型链继承)
           4.子实例.constructor指向超类型构造函数  (出处:原型链继承 ; 解决:手工修改)
           5.实例与原型属性重复   (出处:组合继承调用两次构造函数  ;解决:寄生组合继承,子类型的原型直接指向超类 型的原型)
            6.isPrototypeOf()识别问题 (出处:抛弃原型链继承; 解决:组合继承)
 
1.原型链
function SuperType(){
     this.colors = ["red", "blue", "green"];
}
function SubType(){
}
//继承了SuperType
SubType.prototype = new SuperType();
var instance1 = new SubType();
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
var instance2 = new SubType();
alert(instance2.colors); //"red,blue,green,black"
 
缺点:1.引用类型共享问题
          2.在创建子类型的实例时,不能向超类型的构造函数中传递参数,由于子实例的原型都为超实例,超实例的属性      会共享 
          3.子实例.constructor指向Supertype
优点:可以实现继承
 
2.借助构造函数(经典继承)
function SuperType(name){
this.colors = ["red", "blue", "green"];
this.name = name;
}
function SubType(name){
//
继承了SuperType ,同时还传递了参数
SuperType.call(this, name);
//
实例属性
this.age = 29;
}
 
优点:子类型构造函数中可以向超类型构造函数传递参数,子实例不会共享属性
缺点:方法都在构造函数中定义,因此函数复用就无从谈起了,isPrototypeOf()识别问题
 
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指针,并执行SuperType函数
this.age = age;
}
//继承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
     alert(this.age);
};
var instance1 = new SubType("Nicholas", 29);
 
优点:解决经典继承的缺点,而且,instanceof isPrototypeOf()也能够用于识别基于组合继承创建的对象
缺点:调用了两次父构造函数,子实例和子实例的原型有两套相同的属性,占用内存
 
4.原型式模式
function object(o){
function F(){}
F.prototype = o;
return new F();
}
var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = object(person);
anotherPerson.friends.push("Rob");
var yetAnotherPerson = object(person);
yetAnotherPerson.friends.push("Barbie");
alert(person.friends); //"Shelby,Court,Van,Rob,Barbie"
 
原型式继承改进
 
var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var anotherPerson = Object.create(person, {
name: {
     value: "Greg"
}
});
alert(anotherPerson.name); //"Greg"
 
特点:从本质上讲,object()或者Object.create()对传入其中的对象执行了一次浅复制,
优点:简单,不用设计构造函数,需要的属性再设定
缺点:原型中如果包含引用类型值的属性始终都会共享相应的值,原型模式一样也具有相同问题(基本类型的属性可以在实例中创建同名 属性屏蔽)。
 
 
 5.寄生式继承(原型模式继承的加强)
function createAnother(original){
     var clone = object(original); // 通过调用函数创建一个新对象
     clone.sayHi = function(){ // 以某种方式来增强这个对象
          alert("hi");
     };
     return clone; //返回这个对象
}
 
优点:同上。方法在不扩展原生对象原型的情况下自定义一个扩展型的对象,增加对象的方法。
缺点:同上。使用寄生式继承来为对象添加函数,会由于不能做到函数复用而降低效率,这一点与构造函数模式类似
 
6.寄生组合式继承(推荐)
function inheritPrototype(subType, superType){//替代SubType.prototype = new SuperType();的继承功能,又避免了调用父构造函数 
var prototype = object(superType.prototype); 
subType.prototype = prototype; 
prototype.constructor = subType; 
}
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;
}
inheritPrototype(SubType, SuperType);//继承方法
SubType.prototype.sayAge = function(){
     alert(this.age);
};
 
优点;解决了组合继承的缺点
 
 
 
      
          
posted @ 2016-09-03 16:41  阿巴阿巴55996  阅读(120)  评论(0)    收藏  举报