js中的几种继承方法

时间:2022-09-15 08:11:32

JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一。

继承:子承父业;一个原本没有某些方法或属性的对象,统一写方法,拿到了另外一个对象的属性和方法

下面是js中的几种继承方式

1.改变this指向继承(构造函数继承):继承构造函数中的属性和方法

 function Parent(n){
this.name = n;
this.skill = function(){
console.log(this.name + "是篮球运动员"); //樱木花道是篮球运动员
//泽北荣治是篮球运动员
}
}
Parent.prototype.init = function(){
console.log(123) //123
} // function P2(){
// this.a = 10;
// }
// function P3(){
// this.b = 20;
// }
// function P4(){
// this.c = 30;
// } function Child(n){
// Parent.bind(this,n)();
// P2.bind(this)()
// P3.bind(this)()
// P4.bind(this)() // Parent.call(this,n); Parent.apply(this,arguments);
} var p = new Parent("樱木花道");
console.log(p)
p.skill(); //
p.init() var c = new Child("泽北荣治");
console.log(c)
c.skill(); //
// console.log(c.a)
// console.log(c.b)
// console.log(c.c)
// c.init()

优点:简单方便易操作,可以多继承

缺点:只能继承构造函数,不能继承原型

2.原型对象继承:继承原型

function Parent(n){
this.name = n;
}
Parent.prototype.skill = function(){
console.log(this.name + "是鉴定师"); //大老王是鉴定师
//小老王是鉴定师
} function Child(n){
this.name = n;
} // 注意:对象的深浅拷贝
for(var i in Parent.prototype){
Child.prototype[i] = Parent.prototype[i];
} var p = new Parent("大老王");
console.log(p) //Parent {name: "大老王"}
p.skill(); var c = new Child("小老王");
console.log(c) //Child {name: "小老王"}
c.skill();

优点:简单,方便,可以继承原型身上的方式和属性

缺单:只能继承原型,不方便传参

3.原型链继承:通过给Child设置原型为Parent的实例的方式,给Child添加了一层原型链的方式

 function Parent(n){
this.name = n;
}
Parent.prototype.skill = function(){
console.log(this.name + "是鉴定师"); //大老王是鉴定师
} function Child(){}
Child.prototype = new Parent("小老王"); Child.prototype.skill = function(){
console.log(this.name+"是运动员") //小老王是运动员
} var p = new Parent("大老王");
console.log(p) //Parent {name: "大老王"}
p.skill();
// p是实例(对象),有__proto__属性,指向Parent.prototype var c = new Child();
console.log(c); //Child {}
c.skill();
// c是实例(对象),有__proto__属性,指向Child.prototype,是Parent的实例(对象),有__proto__属性,指向Parent.prototype

优点:既能继承原型,又能继承构造函数

缺点:复杂,不方便传参

4.混合继承:构造函数继承+原型对象继承

 function Parent(n){
this.name = n;
}
Parent.prototype.skill = function(){
console.log(this.name + "是鉴定师"); //大老王是鉴定师
} function P2(){
this.a = 10;
}
P2.prototype.init = function(){
console.log("hello") //hello
} function Child(n){
Parent.call(this,n)
P2.call(this)
}
for(var i in Parent.prototype){
Child.prototype[i] = Parent.prototype[i]
}
for(var i in P2.prototype){
Child.prototype[i] = P2.prototype[i]
} Child.prototype.skill = function(){
console.log(123) //123
} var p = new Parent("大老王");
console.log(p) //Parent {name: "大老王"}
p.skill(); var c = new Child("小老王");
console.log(c) //Child {name: "小老王", a: 10}
c.skill();
c.init();

优点:既能继承构造函数又能继承原型,方便传参,多继承

缺点:复杂

常用的继承方式之一

5.ES6的class继承

class Parent{
constructor(n) {
this.name = n
}
skill(){
console.log(this.name + "是鉴定师") //大老王是鉴定师
//小老王是鉴定师
}
} class Child extends Parent{
constructor(n){
super(n)
}
} var p = new Parent("大老王");
console.log(p) //Parent {name: "大老王"}
p.skill(); var c = new Child("小老王"); //Child {name: "小老王"}
console.log(c)
c.skill();

优点:简单方便易操作,语法层面的继承,属性和方法都能继承,参数很好处理

缺点:兼容性

忽略兼容,常用的继承方式之一