Sean's Blog

An image showing avatar

Hi, I'm Sean

這裡記錄我學習網站開發的筆記
歡迎交流 (ゝ∀・)b

LinkedInGitHub

Understand JavaScript #24 ES6 Class

本文主要內容為探討另一個建立物件和設定原型的方法「ES6 Class」的相關知識。

ES6 與類別 (Classes)

在其他程式語言中 Class 比較偏向是一個模版,而不是一個物件,它只是在告訴我們物件的模樣,直到用 new 關鍵字才會真的建立物件。

然而,JavaScript ES6 的 Class 卻是一個已經被建立的物件,我們只是再用 new 關鍵字從這個物件去建立新物件而已。

不過這也沒問題,畢竟不同程式語言,也沒必要完全照著走嘛 🙄 但是,這有可能就會造成從其他程式語言轉換過來的人,容易誤解了原型繼承的概念,因為像是習慣寫 Java 的人就會把 Class 當作模版來使用。

總而言之,這篇介紹的 ES6 Class 與前篇介紹的 Object.create,都比第一個講的函式建構子好用許多喔!

STEP 1:用 class 定義物件

  • 建構子 (constructor)
  • 方法 (methods)
1class Person {
2  // 建構子 (constructor):就像是函式建構子一樣,預先設定它們的值
3  constructor(firstname, lastname) {
4    this.firstname = firstname;
5    this.lastname = lastname;
6  }
7  // 可以直接取用這邊放的方法
8  greet() {
9    return 'Hi ' + this.firstname;
10  }
11}
12
13var damao = new Person('Damao', 'Huang');
14console.log(damao); // Person {firstname: "Damao", lastname: "Huang"}
15console.log(damao.greet()); // Hi Damao

STEP 2:用 extends 設定原型

這裡使用了 extends 來設定原型,它的效果就相當於 InformalPerson.__proto__ = Person,所以在這邊 Person 就是 InformalPerson 的原型。

1class InformalPerson extends Person {
2  // 呼叫原型物件的建構子
3  constructor(firstname, lastname) {
4    super(firstname, lastname);
5  }
6
7  // 呼叫父類別的方法
8  greetPerson() {
9    return super.greet();
10  }
11
12  // 可以在子類別中覆寫父類別的方法
13  greet() {
14    return 'Yo! ' + this.firstname;
15  }
16}
17
18var sean = new InformalPerson('Sean', 'Huang');
19console.log(sean); // InformalPerson {firstname: "Sean", lastname: "Huang"}
20console.log(sean.greetPerson()); // Hi Sean
21console.log(sean.greet()); // Yo! Sean

這邊有一個重點就是 super 關鍵字:

  • 如果在子類別的 constructor 中使用 super(),就會呼叫原型物件的 constructor,如此一來就能夠傳入初始值到原型鏈裡面
  • 如果想要在子類別中,呼叫父類別的方法來使用,也可以透過 super 這個關鍵字。當 super 不加括號時,代表把 super 當物件使用,此時 super 會指向父類別 Person

另外,也可以在子類別中設定一樣的方法名稱,這麼做的話可以隱藏或覆寫父類別的方法。

語法糖 (Syntactic Sugar)

我們總共提到了三種「建立物件和設定原型」的方法,但其實這些只是不同的語法表達的方式而已,它們底層的原理都是一樣的。

這種狀況我們會說這是 JavaScript 的語法糖 (Syntactic Sugar),表示有很多種不同的方法都可以做到同一件事。

像是函式建構子、Object.create,與 ES6 的 Class,它們本質上都是在做同一件事,我們使用這三種方法時,JavaScript 引擎都是在做原型繼承。

回顧

看完這篇文章,我們到底有什麼收穫呢?藉由本文可以理解到…

  • 使用 ES6 Class 建立物件和設定原型
  • 語法糖讓程式更加簡潔,有更高的可讀性

References