es5和es6類繼承的主要區別

在es5中當我們談到類,就會想到構造函數,原型等,其實在es6中也有這些東西,ES6中的類只是語法糖,它並沒有改變類實現的本質。下面我們來分別看看es5和es6的類的繼承!

1. es5的繼承
function FatherClass(name){
this.family=['father','mother','daughter'];
this.name = name
};
FatherClass.prototype.getName =function(){
console.log(this.name);
};
function ChilderClass(name,age){
//子類繼承父類(沒涉及到父類原型)
FatherClass.call(this,name)
this.age =age;
};
function F(){};
//過渡函數的原型繼承父對象
F.prototype =FatherClass.prototype;
ChilderClass.prototype = new F();
var instance = new ChilderClass('lily',18);

這個就是es5的類繼承,它分兩種繼承方式:構造函數繼承和原型繼承!子類繼承父類的時候,先創造子類的實例對象this,然後再將父類的方法或者屬性添加到this上面(FatherClass.call(this,name)),然後再去繼承原型鏈!如果我們要用es5寫法去實現原生構造函數的繼承(原生構造函數是指語言內置的構造函數)會是怎麼寫呢?

function MyArray() {
  Array.apply(this, arguments);
};
MyArray.prototype = Object.create(Array.prototype);
MyArray.prototype.constructor = MyArray;
var colors = new MyArray();
colors[0] = "red";
colors.length  // 0
colors.length = 0;
colors[0]  // "red"

上面代碼定義了一個繼承 Array 的MyArray類。但是,這個類的行爲與Array完全不一致。之所以會發生這種情況,是因爲子類無法獲得原生構造函數的內部屬性,ES5 是先新建子類的實例對象this,再將父類的屬性添加到子類上,由於父類的內部屬性無法獲取,導致無法繼承原生的構造函數!

2. es6的繼承

還是基於上面的例子用es6的寫法

class FatherClass {
    family = ['father', 'mother', 'daughter'];
    constructor(name) {
        this.name = name
    }
    getName() {
        console.log(this.name);
    }
};

class ChilderClass extends FatherClass {
    constructor(name, age) {
        super(name);
        this.age = age;
    }
};
var instance = new ChilderClass('lily', 18);

看起來是不是舒服多了?這裏類繼承機制完全和es5不一樣,先調用super方法將父類實例對象的屬性和方法加到this上面,然後再用子類的構造函數修改this。在子類的構造函數中,只有調用super之後,纔可以使用this關鍵字,否則會報錯。這是因爲子類實例的構建,基於父類實例,只有super方法才能調用父類實例!

console.log(ChilderClass.__proto__ === FatherClass);//true
console.log(ChilderClass.prototype.__proto__ === FatherClass.prototype);//true

這裏比es6多了個靜態方法繼承,因爲ChilderClass要繼承FatherClass,那麼FatherClass的靜態屬性和方法也都需要繼承,所以 ChilderClass=Object.create(FatherClass)或者 Object.setPrototypeOf(ChilderClass,FatherClass).用es5一樣ChilderClass.prototype也必須是FatherClass.prototype的實例!然後我們看下實現原生構造函數的繼承(原生構造函數是指語言內置的構造函數)

class MyArray extends Array {
constructor(...args) {
  super(...args);
}
};
var colors= new MyArray();
colors[0] = "red";
colors.length  // 1
colors.length = 0;
colors[0]  // underfined

所以總體看來,es5類繼承和es6類繼承區別還是有些區別的!以上爲我個人觀點,如果有不正確的,請指正,不勝感激!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章