您的位置:首页 > Web前端 > JavaScript

javascript的四种继承方式

2017-10-14 16:31 351 查看

原型继承

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;

结语

总结下来其实也很简单,就是让子类原型的原型指针指向父类原型,私有属性写在构造函数里,公有属性写在原型里。
有兴趣的同学可以去实现在父类和子类中间桥接一个类,更能帮助理解!
如果有不正确的地方,欢迎大家拍砖!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript 继承 图片