來了解javacript 類別(classes)吧!

Photo by Markus Spiske on Pexels.com

前言

總算~又開始寫技術文章了,自從開始工作之後自己摸索的時間就少了不少,再加上一些個人的惰性就變成一篇文章也沒有了:D 這段時間變得較為空閒,除了處理學生的問題外也開始複習一些之前學到的技術。尤其在接觸過ROR後我發現物件繼承在許多時候真的相當有用,於是便回頭來看一下在ES6後新增的語法糖,類別(classes),今天打算用一篇簡單的文章介紹一下在JS中你該如何使用類別,希望看完之後能讓你們對於它不再那麼陌生😁

Javascript中的class仍只是單純的物件繼承

class在許多程式語言(Java、Ruby、C)都是相當常見的概念,不過在js中它背後的原理仍只是單純的物件繼承,就像我們利用Object.create或是function constructor一樣。這也就是為什麼在文章的一開始就點明了它只是個語法糖!

基本的class使用

我們很快的看一下簡單的例子,以前我們需要利用function constructor建立這樣的概念

  function Dog(name) {
    this.name = name
  }
  Dog.prototype.bark = function() { console.log('woof')}
  const puppy = new Dog('Danny')
  puppy.name // Danny
  puppy.bark() // woof!

但有了class之後我們就可以將上述的範例改為以下

  class Dog {
    constructor(name) {
      this.name = name
    }
    bark() {
      console.log('woof')
    }
  }

兩者是完全等價的! 但就像我一直在強調的,Js中並沒有class這樣的實體,你宣告出來的其實本體仍是function,它只是替我們做完傳統利用function constructor做的事情罷了!

class 的靜態方法 (Static Method)

靜態方法對於沒有接觸過js以外語言的讀者可能會有點陌生,一般來說我們叫做class method,也就是綁定在這個class上的一些方法,只有該class與繼承的class可以使用你產出的實體無法使用! 我知道這聽起來很讓人困惑,我們接續上方的例子來看吧!

  class Dog {
    constructor(name) {
      this.name = name
    }
    static woo() {
      console.log('wooooooooooooo')
    }
    bark() {
      console.log('woof')
    }
  }
  const puppy = new Dog('Danny')
  puppy.bark() // woof,一般方法可以正常使用
  puppy.woo() // 噴錯,實體無法使用靜態方法
  Dog.woo() // wooooooooooo,只有class可以使用靜態方法

class中的繼承 – extends

你可以簡單的利用extends繼承某個class,我們一樣接續上方的例子,假設現在已經有一個Dog class

  class Pug extends Dog { // 讓Pug繼承Dog
    sadFace() {
      console.log('My face is wrinkle 😢')
    }
  }
  const pug = new Pug('Wang')
  pug.bark() // woof,繼承的方法可以正常使用
  pug.sadFace() // My face is wrinkle 😢,自己的方法可以正常使用
  Pug.woo() // wooooooooooo,會連靜態方法一併繼承

利用super覆寫父層的方法

super關鍵字可以讓你輕鬆的取得來自父層的一些方法或是屬性,並在必要的時候加以修改,接續上方的說明。以下的範例我們試著修改constructor內的屬性以及bark方法,一樣用Pug繼承Dog為例子,目標是在以下的範例中達成兩個效果
1. 在pug constrcutor內新增age屬性
2. 覆寫繼承來的bark方法

  class Pug extends Dog { 
    constructor(name, age) {
      super(name) // Dog內已經有name,可以直接用super繼承屬性不用重寫一次
      this.age = age
    }
    bark() {
     super.bark()
     console.log('I am a cute pug!')
    }
    sadFace() {
      console.log('My face is wrinkle 😢')
    }
  }
  const pug = new Pug('Wang', 5)
  pug.bark() // woof I am a cute pug!
  pug.age // 5

super在js中原理與繼承鏈相同,當目前的scope中沒有對應的方法便會利用繼承鏈往上找! 善用super可以精巧的客製化繼承的clss!

結語

這篇文章中我們介紹了基本的class使用,其中包含著constructor、extends以及super的說明,並沒有接觸到太多的底層原理! 希望透過這篇文章大家可以對這個出來已久的玩意兒不再那麼陌生囉!

發表留言