寒潮ing,你可能在FaceTest中遇到(4)—— 常見的繼承方式以及缺點


建立一個基礎的父類構造函數javascript

function God(name='god',age='88') {
    this.name = name;
    this.age = age;
    this.sayName = function() {
        console.log(this.name);
    }
}
God.prototype.sayAge = function() {
    console.log(this.age);
}
複製代碼

咱們能夠經過下面的幾種繼承方式得到父類的java


1.原型鏈繼承算法

function Son(name='son') {
    this.name = name;
}
Son.prototype = new God();
let mySon = new Son();
console.log(mySon.name);//son
console.log(mySon.age);//88
mySon.sayName();// son
mySon.sayAge();// 88
console.log(mySon instanceof Son);// true
console.log(mySon instanceof God);// true
複製代碼

實現比較簡單,可是 原型對象的全部屬性被全部實例共享
借用原型鏈繼承上面代碼函數

let mySon1 = new Son();
let mySon2 = new Son();
mySon1.age = '18';
console.log(mySon2.age);//18
複製代碼

2.構造繼承post

function Son(name='son') {
    God.call(this);
    this.name = name;
}

let mySon = new Son();
console.log(mySon.name);//son
console.log(mySon.age);//88
mySon.sayName();// son
mySon.sayAge();// undefined
console.log(mySon instanceof Son);// true
console.log(mySon instanceof God);// false
複製代碼
let mySon1 = new Son();
let mySon2 = new Son();
mySon1.age = '18';
console.log(mySon2.age);//88
複製代碼

構造繼承避免了共享屬性的問題,可是不能繼承父類原型上的屬性或者方法,實例化對象是子類(Son)ui


3.組合繼承this

function Son(name='son') {
    God.call(this);
    this.name = name;
}
Son.prototype = new God();
// 注意這裏要改變constructor 指向
Son.prototype.constructor = Son;

let mySon = new Son();
console.log(mySon.name);// son
console.log(mySon.age);// 88
mySon.sayName();// son
mySon.sayAge();// 88
console.log(mySon instanceof Son);// true
console.log(mySon instanceof God);// true
複製代碼

綜合了原型鏈繼承和組合繼承的優勢,除了調用兩次父類外幾乎完好點spa


4.實例繼承prototype

function Son(name='son') {
    let instance = new God();
    instance.name = name;
    return instance
}

let mySon = new Son();
console.log(mySon.name);// son
console.log(mySon.age);// 88
mySon.sayName();// son
mySon.sayAge();// 88
console.log(mySon instanceof Son);// false
console.log(mySon instanceof God);// true
複製代碼

繼承的是父類God,而不是子類Soncode


5.拷貝繼承

function Son(name='son') {
    let obj = new God();
    for (let key in obj) {
        Son.prototype[key] = obj[key]
    }
    Son.prototype.name = name;
}

let mySon = new Son();
console.log(mySon.name);// son
console.log(mySon.age);// 88
mySon.sayName();// son
mySon.sayAge();// 88
console.log(mySon instanceof Son);// true
console.log(mySon instanceof God);// false
複製代碼

缺點比較明顯,須要屢次循環,並且沒法遍歷不可枚舉屬性


6.寄生組合繼承

function Son(name='son') {
    God.call(this);
    this.name = name;
}
// 當即執行函數
(function() {
    // 建立一箇中間函數
   let Mid = function() {}
   Mid.prototype = God.prototype;
   Son.prototype = new Mid();
})()
// 注意這裏要改變constructor 指向
Son.prototype.constructor = Son;

let mySon = new Son();
console.log(mySon.name);// son
console.log(mySon.age);// 88
mySon.sayName();// son
mySon.sayAge();// 88
console.log(mySon instanceof Son);// true
console.log(mySon instanceof God);// true
複製代碼

缺點是實現複雜,幾乎完美的繼承



7.9012年了 ES6的class繼承該用起來了

class God {
    constructor(name='god',age='88') {
        this.name = name;
        this.age = age;
    }
}
class Son extends God {
    constructor(name='son',sex='M') {
        super(name);
        this.sex = sex;
    }
}

let mySon = new Son();
console.log(mySon.name);// son
console.log(mySon.age);// 88
console.log(mySon.sex);// M
console.log(mySon instanceof Son);// true
console.log(mySon instanceof God);// true
複製代碼
相關文章
相關標籤/搜索