iT邦幫忙

2021 iThome 鐵人賽

DAY 18
0
Modern Web

JavaScript學習日記系列 第 18

JavaScript學習日記 : Day18 - Class

  • 分享至 

  • xImage
  •  

在平時開發時,我們會遇到要創建許多類型相似的object,之前的文章有提到使用new操作符配合function可以達到我們的需求,而今天要介紹的是Class。

1. 基本語法

calss ownClass {
    constructor() {}
    method1() {}
    method2() {}
    method3() {}
}

實際舉個例子說明new class的一些觀念:

class Cat {
    constructor(name) {
        this.name = name
    }
    jump() {
        console.log(`${this.name} jump!`)
    }
    eat() {
        console.log(`${this.name} eat!`)
    }
}

let catA = new Cat("CatA");

console.log(typeof Cat); // function

console.log(Cat === Cat.prototype.constructor) // true

console.log(Cat.prototype.jump) // console.log(`${this.name} jump!`)

console.log(Object.getOwnPropertyNames(Cat.prototype)) // ["constructor", "jump", "eat"]

2. 與構造器(Constructor)的差別

許多文章都認為class只是語法糖,可以用一般的構造器重複寫出相同於上面Cat的功能:

function Cat(name) {
    this.name = name
}

Cat.prototype.jump = function() {
    console.log(`${this.name} jump!`)
}

Cat.prototype.eat = function() {
    console.log(`${this.name} eat!`)
}

let catA = new Cat("CatA");

構造器與Class差別:

  1. 透過Class創建的函數內部有[[IsClassConstructor]]:true,與一般函數不同。
  2. 無法用()呼叫,只能用new操作符
  3. Class將prototype中的所有method都標示為enumerable:false,所以new Class產出的object,透過for..in是不會出現這些方法的。

3. Class表達式

與函數一樣有聲明與表達式兩種,上面介紹的是聲明式,以下是表達式的例子:

let Cat = class {
    jump() {
        console.log(`${this.name} jump!`)
    }
}

類似於函數的具名表達式,Class也有,不過只在函數內可見:

let Cat = class CatClass {
    jump() {
        console.log(`${this.name} jump!`)
    }
    getClassName() {
        console.log(CatClass)
    }
}

let catA = new Cat;
catA.getClassName(); class CatClass{...}
console.log(CatClass); // CatClass is not defined

4. Getter/Setter

class Cat {
    constructor(name) {
        this.name = name
    }
    get name() {
        return this._name
    }
    set name(value) {
        this._name = value
    }
}

let catA = new Cat("catA");
console.log(catA.name); // catA
catA.name = 'catB';
console.log(catA.name) // catB

5. Class新增屬姓

在Class中新增的屬性會獨立的在每個object中新增,而不是新增在prototype中。

class Cat {
    name = "catA";
    
    jump() {
        console.log(`${this.name} jump!`)
    }
}

new Cat().jump(); // catA jump!

新增屬性也可以作為Day11函數綁定的一個解法:

class Cat {
    constructor(name) {
        this.name = name
    }
    
    jump() {
        console.log(`${this.name} jump!`)
    }
}

let catA = new Cat("catA");

setTimeout(catA.jump,1000) // undefined

可以運用箭頭函數的特性,this會指向父作用域的this,在下面的例子中就會指向Cat這個function的this,也就會指向catA。

class Cat {
    constructor(name) {
        this.name = name
    }
    
    jump = () => {
        console.log(`${this.name} jump!`)
    }
}

let catA = new Cat("catA");

setTimeout(catA.jump,1000) // catA jump!

上一篇
JavaScript學習日記 : Day17 - Async Await
下一篇
JavaScript學習日記 : Day19 - Class繼承
系列文
JavaScript學習日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言