javascript的四种继承方式

原型继承

function Super() {
  //自定义属性和方法
}
function Sub() {
  //自定义属性和方法
}
Sub.prototype = new Super();
Sub.prototype.constructor = Sub;

原型继承的优点是简单,缺点也很明显有两点,第一点、子类原型作为父类的实例时,用的是无参构造,也就是说子类构造函数的参数无法传递。第二点、当父类构造函数中使用引用数据类型时,子类实例对象的这个数据类型是共享的。

function Super() {
  //自定义属性和方法
  this.name = 'superName'
  this.colors = ['r', 'g', 'b']
}
function Sub() {
  //自定义属性和方法
}
Sub.prototype = new Super();
Sub.prototype.constructor = Sub;
var sub = new Sub();
var sub2 = new Sub();
sub.colors.push("OvO")
sub.name = 'subName'
console.log(sub)
console.log(sub2)




借用构造函数继承

借用构造函数可以很好地解决上面的问题

function Super(name) {
  //自定义属性和方法
  this.name = name
  this.colors = ['r', 'g', 'b']
}
function Sub(name) {
  //自定义属性和方法
  Super.apply(this, arguments)
}
var sub = new Sub('subName');
var sub2 = new Sub('another');
sub.colors.push("OvO")
console.log(sub)
console.log(sub2)



这种继承方式本质上只是借用了父类构造函数的作用域,优点同样是很简单,缺点则是子类实例对象无法继承父类原型的属性方法,而且无法共享同一个方法,因为实例对象全部借用构造函数私有化了,这问题就大了,如果你需要共享一个很大的数据集,每生成一个子类对象,你就重新创建一遍,很浪费内存,完全没有必要。

组合继承

上面两种继承明显是互补的,因此把它组合起来,问题不就解决了吗!

function Super(name) {
  //自定义属性和方法
  this.name = name
  this.colors = ['r', 'g', 'b']
}
//把共享的属性方法用下面这种方式写出来,直接用字面量对象写会破坏继承链
Super.prototype.sayName = function() {

}
function Sub(name) {
  //自定义属性和方法
  Super.apply(this, arguments)
}
Sub.prototype = new Super();
Sub.prototype.constructor = Sub;
Sub.prototype.sayColor = function() {

}
var sub = new Sub('subName');
sub.colors.push("OvO")
console.log(sub)

融合了借用构造函数和原型式继承的优点,较完美的实现了继承。缺点则是调用了两次父类构造函数,子类原型里被覆盖的属性也能说明被调用了两次,追求完美的同学可以用下面的寄生组合式继承。


寄生式组合继承

function inheritPrototype(subType,superType) {
  //ES5新增方法
  var prototype = Object.create(superType.prototype);
  prototype.constructor = subType;
  subType.prototype = prototype;
}
function Super(name) {
  //自定义属性和方法
  this.name = name
  this.colors = ['r', 'g', 'b']
}
//把共享的属性方法用下面这种方式写出来,直接用字面量对象写会破坏继承链
Super.prototype.sayName = function() {

}
function Sub(name) {
  //自定义属性和方法
  Super.apply(this, arguments)
}
inheritPrototype(Sub, Super);
Sub.prototype.sayColor = function() {

}
var sub = new Sub('subName');
sub.colors.push("OvO")
console.log(sub)




不理解inhetirPrototype函数的同学可以看一下下面两行代码,起到的效果是一样的

Sub.prototype.__proto__ = Super.prototype;
Sub.prototype.constructor = Sub;

结语

总结下来其实也很简单,就是让子类原型的原型指针指向父类原型,私有属性写在构造函数里,公有属性写在原型里。
有兴趣的同学可以去实现在父类和子类中间桥接一个类,更能帮助理解!
如果有不正确的地方,欢迎大家拍砖!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值