今天會來繼續介紹語法糖Class
的語法部分,會介紹到的分別為:
首先昨天已經知道了,class
可以依靠constructor
跟prototype
的原理來去實作出像是其他程式語言的繼承效果,但是class
以及class
之間的繼承還是一個問題,為了這件事情,JavaScript
有提供在class
中可以使用extends
跟super
來解決這件事情。
原本單純使用class
來寫會是長這樣:
class Parent
使用extends
關鍵字的語法是:
class Child extends Parent
這邊使用MDN上面的範例修改過後來做講解:
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
speak() {
console.log(`${this.name}說話了。`);
}
}
class Dog extends Animal {
constructor(name) {
super(name); // call the super class constructor and pass in the name parameter
}
speak() {
console.log(`${this.name}正在叫。`);
}
}
const a = new Dog('Mitzie');
a.speak(); // Mitzie barks.
一步步去拆分extends
跟super
做了哪些事情。
extends
指定 Animal class
Dog這個新的class
想要獲得Animal這個舊的class
的繼承,相當於就直接繼承了Animal裡面所有的Properties
和 Method
,那這邊會有一個問題出現,那super
的作用何在?
super
呼叫 extends
指定的 Animal class
沒有加super
直接把super(name);
給刪掉的話,會報錯,訊息如下:
ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
但如果是把:
constructor(name) {
super(name);
}
這段完全刪掉的話,不會報錯,然後結果也看起來一模一樣。
這是因為今天如果不需要透過Dog去新增屬性(就是寫在constructor
裡面的東西),只是增加方法,或是使用繼承而來的方法,那就可以把super
省略掉也可以。
簡單來說,用到super
可以讓JavaScript
判斷說 extends
過的那個class,有沒有需要替換掉那個繼承的東西,示意圖:
class Dog extends Animal {
speak() {
// 現在這個裡面的東西會被當成 Dog.stop()
// 而不是被當成來自於 class Animal 的 speak()
}
}
JavaScript
沒辦法判斷到底要以誰的為準,所以創造出了叫做super
的關鍵字,主要的功能如下:
constructor
假如說,我想要讓Dog創造出來的實例在說話speak()
時,多說一句你好sayHi()
:
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
speak() {
console.log(`${this.name}說話了。`);
}
}
class Dog extends Animal {
constructor(name) {
super(name);
}
sayHi() {
console.log("hi");
}
speak() {
super.speak();
this.sayHi();
}
}
const a = new Dog("dog");
a.speak(); //dog說話了。 hi
這樣的話,就是讓Dog在繼承了Animal這個class所有的屬性之外,也可以去使用Animal的speak()方法,然後在這個基礎之外,再去新增新的功能也是沒有問題。
透過這種使用extends
跟super
的搭配就可以做到讓彼此class之間的繼承。
static methods
中文是叫做靜態方法,就是我可以在class裡面的constructor
去進行呼叫靜態方法,但創造出來的實例是無法去取用的,舉例來說:
class Person {
constructor(name) {
this.name = name;
}
static sayHello(name) {
console.log(`${name},How are you`);
}
}
Person.sayHello("vic");
假如使用static
這個關鍵字在class內的Method中,那個Method就會變成static method
,像這邊來說,Person
就變得可以使用sayHello
這個方法,但同時創造出來的實例就將會變得無法執行,可以來試試看。
const apple = new Person("apple");
apple.sayHello(); // TypeError: apple.sayHello is not a function
會報錯,找不到無法使用。
可以理解成,一般狀態下是動態的,創建出來的實例可以隨著自身的class
動態使用它,可以用static
使其變成靜態,在靜態時可以直接從class
取用方法。
而關於靜態時候的屬性也是可以做得到的,靜態就屬性就代表可以直接從class
取用的屬性,舉例來說:
class Apple {
static color = "red";
}
console.log(Apple.color); // red
加上了static
的屬性就可以直接在class
去使用的,像上面就可以直接用Apple去取得color的屬性,就其實就相當於直接給Apple做一個賦值的動作。
今天介紹了一些Class
語法糖的使用方式,可能就算不會寫class
也一樣可以寫JavaScript
,但是學會了這個技巧可以幫助成為自己成為一個更棒的工程師,基本的class就先介紹到這邊~
[1] MDN - Classes
[2] JavaScript | ES6 中最容易誤會的語法糖 Class - 基本用法
[3] Class inheritance