JavaScript各种继承方式和优缺点
原型链继承
function SuperClass() {
this.superValue = true;
}
//为父类添加公有方法
SuperClass.prototype.getSuperValue = function () {
return this.superValue;
};
//声明子类
function SubClass() {
this.subValue = false;
}
//继承父类
SubClass.prototype = new SuperClass();//将父类对象赋值给子类原型,子类原型可访问父类原型上的属性和方法--类式继承原理
//子类添加公有方法
SubClass.prototype.getSubValue = function() {
return this.subValue;
};
缺点:
1、子类通过其原型prototype对父类实例化,继承了父类。但当父类中的共有子类通过其原型prototype对父类实例化,继承了父类。但当父类中的共有属性是引用类型
时,会在子类中被所有的实例共用,如此在一个子类实例中更改从父类中继承过来的公有属性时,会影响到其他子类
2、由于子类是通过原型prototype实例化父类实现继承的,所以在创建子类的时候,无法向父类传递参数,
借用构造函数(经典继承)
function SuperClass(id) {
this.book = ['javascript','html','css'];//引用类型共有属性
this.id = id;//值类型公有属性
}
//父类声明原型方法
SuperClass.prototype.showBooks = function() {
console.log(this.books);
}
//声明子类
function SubClass(id) {
//继承父类
SuperClass.call(this,id);
}
优点:
1、避免了引用类型的属性被所有实例共享
2、可以向父类传参 缺点:
1、父类的原型方法不会被子类继承 2、方法都在构造函数中定义,每次创建实例都会创建一遍方法。
组合式继承
原型链继承和经典继承双剑合璧
function SuperClass(name) {
this.name = name;
this.book = ['javascript','html','css'];
}
SuperClass.prototype.getName = function () {
console.log(this.name);
};
function SubClass(name,time) {
//构造函数式继承,继承父类name属性
SuperClass.call(this,name);
this.time = time;
}
//类式继承,子类原型继承
SubClass.prototype = new SuperClass();
//子类原型方法
SubClass.prototype.getTime = function () {
console.log(this.time);
};
优点:
融合原型链继承和构造函数的优点,是 JavaScript 中最常用的继承模式
缺点:
父类的构造函数执行了两遍:一次在子类的构造函数中call方法执行一遍,一次在子类原型实例化父类的时候执行一遍。
原型式继承
类似于Object.create的模拟实现,将传入的值当作创建对象的原型
function createObj(o) {
function F(){}
F.prototype = o;
return new F();
}
ECMAScript5通过新增 Object.create()方法规范了原型式继承 缺点:包含引用类型的属性值始终都会共享相应的值,这点跟原型链继承一样。
寄生组合式继承
借用构造函数
+ 原型式继承
的结合体;是一种比较常见的成熟的方式
// 原型继承
function inheritPrototype(subType, superType){
var prototype = Object.create(superType.prototype); // 创建对象
prototype.constructor = subType; // 增强对象
subType.prototype = prototype; // 指定对象
}
// 父类初始化实例属性和原型属性
function SuperClass(name){
this.name = name;
this.book = ['javascript','html','css'];
}
SuperClass.prototype.getName = function(){
alert(this.name);
};
// 借用构造函数继承
function SubClass(name, age){
SuperClass.call(this, name);
this.time = time;
}
// 将父类原型指向子类
inheritPrototype(SubClass, SuperClass);
// 新增子类原型属性
SubClass.prototype.getTime = function(){
alert(this.time);
}
var instance1 = new SubClass("js",12);
var instance2 = new SubClass("scss", 12);
es6新增的extends方式
Class 可以通过extends关键字实现继承;他的继承核心和寄生组合式继承很像
class SuperClass {
}
class SubClass extends SuperClass {
constructor(x, y) {
super(x, y); // 调用父类的constructor(x, y)
this.color = color;
}
}
小红包免费领
小礼物走一走
部分内容来源于网络,如有侵权,请留言或联系994917123@qq.com;访问量:waiting;访客数:waiting