js中的幾種繼承方法
阿新 • • 發佈:2019-09-21
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();
優點:簡單方便易操作,語法層面的繼承,屬性和方法都能繼承,引數很好處理
缺點:相容性
忽略相容,常用的繼承方式之