ES6提供了更接近傳統(tǒng)語言的寫法,引入了Class(類)這個概念。新的class寫法讓對象原型的寫法更加清晰、更像面向?qū)ο缶幊痰恼Z法,也更加通俗易懂。
class Animal {
// 構(gòu)造方法,實例化的時候?qū)徽{(diào)用,如果不指定,那么會有一個不帶參數(shù)的默認(rèn)構(gòu)造函數(shù).
constructor(name,color) {
this.name = name;
this.color = color;
}
// toString 是原型對象上的屬性
toString() {
console.log('name:' + this.name + ',color:' + this.color);
}
}
var animal = new Animal('dog','white');
animal.toString();
console.log(animal.hasOwnProperty('name')); //true
console.log(animal.hasOwnProperty('toString')); // false
console.log(animal.__proto__.hasOwnProperty('toString')); // true
class Cat extends Animal {
constructor(action) {
// 子類必須要在constructor中指定super 方法,否則在新建實例的時候會報錯.
// 如果沒有置頂consructor,默認(rèn)帶super方法的constructor將會被添加、
super('cat','white');
this.action = action;
}
toString() {
console.log(super.toString());
}
}
var cat = new Cat('catch')
cat.toString();
// 實例cat 是 Cat 和 Animal 的實例,和Es5完全一致。
console.log(cat instanceof Cat); // true
console.log(cat instanceof Animal); // true
上面代碼首先用class定義了一個“類”,可以看到里面有一個constructor方法,這就是構(gòu)造方法,而this關(guān)鍵字則代表實例對象。簡單地說,constructor內(nèi)定義的方法和屬性是實例對象自己的,而constructor外定義的方法和屬性則是所有實例對象可以共享的。
Class之間可以通過extends關(guān)鍵字實現(xiàn)繼承,這比ES5的通過修改原型鏈實現(xiàn)繼承,要清晰和方便很多。上面定義了一個Cat類,該類通過extends關(guān)鍵字,繼承了Animal類的所有屬性和方法。
super關(guān)鍵字,它指代父類的實例(即父類的this對象)。子類必須在constructor方法中調(diào)用super方法,否則新建實例時會報錯。這是因為子類沒有自己的this對象,而是繼承父類的this對象,然后對其進行加工。如果不調(diào)用super方法,子類就得不到this對象。
ES6的繼承機制,實質(zhì)是先創(chuàng)造父類的實例對象this(所以必須先調(diào)用super方法),然后再用子類的構(gòu)造函數(shù)修改this。