JavaScript能夠透過原型來實現繼承,而非使用傳統的類別,這點,讓許多的開發人員一開始的確是霧煞煞,非常地不習慣。
先撇除原型繼承這樣的方式所帶來的好壞,畢竟使用類別來實現繼承已經有相當長的一段時間,不管是技術上或是理論上的,可說是相當地成熟,所以JavaScript不可避免地也走上同樣的道路,甚至出現了類似傳統物件繼承的函式庫,有鑑於此,在ES6版本總算將傳統物件繼承的語法給標準化,讓我們可以在JavaScript使用class關鍵字。
請注意,class關鍵字在JavaScript是語法糖,JavaScript骨子裡仍然使用原型作為繼承的執行方式,即便如此,我想那些熟悉後端程式語言的開發者,在前端看到class關鍵字,心理應該很高興才是。
語法糖
https://zh.wikipedia.org/zh-tw/%E8%AF%AD%E6%B3%95%E7%B3%96
class Member {
constructor(_name) {
this.name = _name;
}
greeting() {
console.log(`Hello!${this.name}`);
}
}
let mem1 = new Member('Mary');
mem1.greeting(); //Hello!Mary
console.log(mem1 instanceof Member); //true
使用class關鍵字建立Member類別。
定義建構子constructor( ),建立物件的同時,初始化物件,指定name屬性值。
定義方法greeting( )。
使用new關鍵字,建立mem1物件。
比對ES5的寫法:
function Member(_name) {
this.name = _name;
}
Member.prototype.greeting = function () {
console.log(`Hello!${this.name}`);
}
個人是比較推薦ES6的class。
上面的範例,不管是ES5函式建構或ES6 class定義的方法,都是屬於物件層級,也就是說,只有創立新物件,才能使用定義的方法。
除此之外,我們也可以定義類別層級的方法,直接在類別就可以使用定義的方法,無須再創立新物件。
class Member {
constructor(_name) {
this.name = _name;
}
greeting() {
console.log(`Hello!${this.name}`);
}
static run() {
console.log('running...');
}
}
let mem1 = new Member('Mary');
mem1.greeting();
mem1.run();
在run( )前加上static關鍵字,表示run( )為類別層級的方法。
由於run( )為類別層級,所以無法透過mem1物件存取。
只能透過Member類別存取。
Member.run(); //running...
class Person {
constructor(_name) {
this.name = _name;
}
run() {
console.log(`${this.name} is running...`);
}
}
class Member extends Person {
constructor(_name, _age) {
super(_name);
this.age = _age;
}
greeting() {
console.log(`${this.name} is ${this.age}`);
}
}
let mem1 = new Member('Mary', 18);
mem1.greeting(); //Mary is 18
mem1.run(); //Mary is running...
先定義Person類別,再定義Member類別,並利用extends關鍵字,使Member類別繼承Person類別,此時Person類別為基底類別,Member類別為衍生類別。
Member類別的建構子,可以透過super關鍵字,呼叫基底類別(Person)的建構子,並傳送參數_name。
藉super來定義由Member類別建立的物件的name屬性。
而Member物件的age屬性,則是由自身的建構子定義的。
由於Member類別繼承自Person類別,所以Member物件可以存取Person類別中,定義的run( )函式。
由結果可以看出mem1,具有name屬性,也可以存取run( ),這就是繼承的最大用意。
可以讓我們的程式具備重複利用性以及擴充性的優點。
但如果,使用Person類別建立物件,由於mem2物件不是由Member類別建立的,所以它自然沒有age屬性,以及無法存取greeting( )函式。
let mem2 = new Person('Bill', 18);
console.log(mem2.age);
mem2.run();
mem2.greeting();
結果
參考來源:
忍者:JavaScript開發技巧探秘