转载

面向对象的程序设计之继承

以下是几种js中实现继承的方式方法,它们也是各自有各自的优缺点,选择哪一种根据自己的应用而定,最适合自己的才是最好的.

通过原型链继承

function SuperType(){  this.name = 'yahualingfeng'; } SuperType.prototype.friends = ['David','Bob','Lucy']; SuperType.prototype.sayName = function(){   alert(this.name); }; function SubType(){  this.age = 30;  } SubType.protoType = new SuperType();//通过原型对象继承SuperType var subType1 = new SubType(); var subType2 = new SubType(); subType1.friends.push('Jake'); console.log(subType1.friends); // ['David','Bob','Lucy','Jake'] console.log(subType2.friends); // ['David','Bob','Lucy','Jake'] 

缺点:

  • 引用类型的值在原型中会被所有实例共享.

  • 不能向超类的构造函数中传递参数

借用构造函数继承

借用构造函数继承是将超类( SuperTyoe )所有的属性和方法都写在构造函数中,最后在函数( SubType )体内通过 call 方法调用超类.

function SuperType(){  this.name = 'yuhualingfeng';  this.friends =['David','Bob','Lucy'];  this.sayName = function(){   alert(this.name);  } } function SubType(){  SuperType.call(this); } var subType = new SubType(); subType.sayName();  

缺点:方法的定义都存在构造函数中,导致函数无法被复用.

组合继承

组合继承是原型链继承和构造函数继承的结合体,结合了二者的优点,即实现了函数的复用,也不会导致引用类型值在多个实例中共享.

 function SuperType(){  this.name='yuhualingfeng';  this.friends=['David','Bob','Lucy']; } SuperType.prototype.sayName = function(){  alert(this.name); }; function SubType(){  SuperType.call(this); } SubType.prototype = new SuperType(); var subType = new SubType();  

缺点:

  • 超类函数被执行了两次.

  • 超类构造函数 SuperType 自身的属性( name , friends )被重复定义,即出现在 SubType 的构造函数中,也出现在 SubType 的原型对象中.

原型继承

原型继承是继承自一个对象而不是引用类型.

function object(obj){  function F(){}  F.prototype = obj;  return new F(); }

这里的object方法接收obj对象,并将对象赋值给一个空函数的原型,并返回空函数的实例.

 var person = {  name:'yuhualingfeng',  friends:['David','Bob','Lucy'] };  var anotherPerson = object(person); anotherPerson.name = 'Jake'; anotherPerson.friends.push('Marry');  console.log(anotherPerson.friends); //['David','Bob','Lucy','Marry']  console.log(person.friends); //['David','Bob','Lucy','Marry']  

如果不想创建构造函数,只想让一个对象和另一个对象保持一致的情况下,原型继承是完全可以胜任的,不过有一点要注意的是,假如继承的属性值为引用类型时,还是会相互影响的.

寄生继承

寄生继承是基于原型继承的基础上扩展自己的属性和方法.

function createrAnother(obj){  var clone = object(obj);  clone.sayHi=function(){   alert('Hi!');  }  return clone; } var person = {  name:'yuhualingfeng' }; var anotherPerson = createAnother(person); anohterPerson.sayHi();  // Hi 

寄生继承也是和原型继承一样也是继承对象,并产出对象.

寄生组合继承

顾名思义,寄生组合继承是集寄生继承和组合继承的结合体,它结合了二者的优点.

 //继承Supertype的原型对象 function inheritProtoType(SuperType,SubType){   var prototype = object(SuperType.prototype);   prototype.constructor = SubType;   SubType.prototype = prototype; } function SuperType(){  this.name = 'yuhualingfeng';  this.friends = ['David','Bob','Lucy']; } function SubType(){  ////继承Supertype的构造函数属性  SuperType.call(this);  this.age = 30; } inheritProtoType(SuperType,SubType); var subType = new SubType(); 

寄生组合继承是前面几种继承思想碰撞在一起的产物,是执行效率最高也是应用面最广的.

总结

原型链继承 是通过为原型对象赋值,不足之处为引用类型值会被多个实例共享, 构造函数继承 解决了 原型链继承 的问题,同时也暴露出新的问题是函数的复用无法实现,然后我们结合二者的优缺点,构造出了 组合继承 , 组合继承 基本上满足了我们想要的继承结果.

考虑到执行的效率,我们构思出了 寄生继承 (基于原型继承),并将 寄生继承组合继承 结合,最终得出了继承的最优解决方案' 寄生组合继承 .

正文到此结束
Loading...