iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0

前言

今天會來繼續介紹語法糖Class的語法部分,會介紹到的分別為:

  • 「extends」、「super」 keywords
  • static properties and methods

extends and super

首先昨天已經知道了,class可以依靠constructorprototype的原理來去實作出像是其他程式語言的繼承效果,但是class以及class之間的繼承還是一個問題,為了這件事情,JavaScript有提供在class中可以使用extendssuper來解決這件事情。

原本單純使用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.

一步步去拆分extendssuper做了哪些事情。

  1. 會發現說Dog使用 extends 指定 Animal class

Dog這個新的class想要獲得Animal這個舊的class的繼承,相當於就直接繼承了Animal裡面所有的PropertiesMethod,那這邊會有一個問題出現,那super的作用何在?

  1. 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的關鍵字,主要的功能如下:

  • 使用supe(...)的方式,來指定可以使用繼承的constructor
  • 使用super.method(...)的方式來直接呼叫那個方法

假如說,我想要讓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()方法,然後在這個基礎之外,再去新增新的功能也是沒有問題。

透過這種使用extendssuper的搭配就可以做到讓彼此class之間的繼承。

static methods and properties

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就先介紹到這邊~

reference

[1] MDN - Classes
[2] JavaScript | ES6 中最容易誤會的語法糖 Class - 基本用法
[3] Class inheritance


上一篇
JS之路 Day06 - 語法糖Class(上)
下一篇
JS之路 Day08 - What is Set ?
系列文
JavaScript 之路,往前邁進吧!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言