---
# System prepended metadata

title: Javascript Class 類
tags: [Javascript]

---

# Javascript Class 類

## 定義

類為特殊的函式，類也具有 類表達式 與 類陳述式 兩種形式。

### 類陳述式
```javascript
// 定義 類的基本方式
class Polygon {
  constructor(height, weight){
    this.height = height;
    this.weight = weight;
  }
}
```

### 類表達式
```javascript
// 不具名類
let Polygon = class {
  constructor(height, weight){
    this.height = height;
    this.weight = weight;
  }
}
console.log(Polygon.name) // Polygon

let Polygon2 = class Polygon2 {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}
console.log(Polygon2.name) // Polygon2

```

#### 類 主體與方法定義

主體為`{}`內包含的部分，可在其中定義其成員(members)與方法(methods)或是建構子(constructor)

##### 建構子 Constructor
建構子作為定義類的初始化預設值使用，一個類只能有一個constructor，若定義多個constructor時則會SyntaxError，如果不需要定義預設值則，constructor也可以省略。

##### 方法 Methods

```javascript
class Polygon {
    // constructor
    constructor(height, width) {
        this.height = height;
        this.width = width;
    }
    // Getter
    get area() {
        return this.calcArea()
    }
    // Method
    calcArea() {
        return this.height * this.width;
    }
}
const square = new Polygon(10, 10);

console.log(square.area);

```
![](https://i.imgur.com/0Pe7T9M.png)


> ##### GETTER | SETTER
> getter method 是在 class 中沒有帶參數就可以回傳值的方法，可以透過 get 設定；setter method 則是可以透過 `=` 來對物件賦值，可以使用 set 來設定
> ```javascript
> class Person {
>  constructor({ firstName, lastName, country = 'Taiwan' } = {}) {
>    this.firstName = firstName;
>    this.lastName = lastName;
>    this.country = country;
>  }
>
>  //  getter method
>  get name() {
>    return this.firstName + ' ' + this.lastName;
>  }
>
>  //  setter method
>  set name(input) {
>    [this.firstName, this.lastName] = input.split(' ');
>  }
>}
>
> let aaron = new Person({ firstName: 'Aaron', lastName: 'Chen' });
> console.log(aaron.name); // 使用 getter method，Aaron Chen
> aaron.name = 'Peter Chen'; // 使用 setter method
> console.log(aaron.name); // Peter Chen
> ``` 

##### 靜態方法 static

靜態方法不需要實體化它所屬類別的實例就可以被呼叫，它也無法被已實體化的類別物件呼叫。靜態方法經常被用來建立給應用程式使用的工具函數。

```javascript

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
  
    static displayName = 'Point';

    static distance(a, b) {
        const dx = a.x - b.x;
        const dy = a.y - b.y;

        return Math.sqrt(dx*dx + dy*dy);
    }
}

const p1 = new Point(5, 5);
const p2 = new Point(10,10);

p1.displayName;
// undefined
p1.distance;
// undefined

console.log(Point.displayName);
// "Point"
console.log(Point.distance(p1, p2));
// 7.0710678118654755


// 呼叫靜態方法的第二種方式

class Bird {
  constructor({ color = 'red' } = {}) {
    this.color = color;
  }

  static changeColor(bird, color) {
    // this 原本指稱的是所建立的 Bird 這個 Class
    bird.color = color;
  }
}

let redBird = new Bird();
console.log(redBird.color); // red
// redBird.changeColor('blue')    // redBird.changeColor is not a function

Bird.changeColor(redBird, 'blue');
console.log(redBird.color); // blue

```

### 使用 extends 來進行繼承創建子類

```javascript

class Person {
  constructor({ name, age = 18 } = {}) {
    this.name = name;
    this.age = age;
  }

  dance() {
    console.log('old dance');
  }
}

class Student extends Person {
  constructor({ name, age, interestLevel = 5 } = {}) {
    // 因為這是 extends from Person，所以我們必須要在為 instance 賦值前，
    // 在 Student constructor 裡面呼叫 super function，
    // 呼叫 super function 的意思就是呼叫 Person 的 constructor function。
    super({ name, age });
    this.name = name;
    this.age = age;
    this.interestLevel = interestLevel;
    this.grades = new Map();
  }

  // 如果 traditional = true，則使用 Person 的 dance()；否則...
  // 也就是說，subclass 是可以覆蓋 superclass 的 method
  dance(traditional) {
    if (traditional) {
      super.dance(); // 呼叫 Person 的 dance method
    } else {
      const dances = ['lyrical', 'tap', 'ballet', 'jaz'];
      console.log(
        `${this.name} is doing the ${dances[Math.floor(Math.random() * dances.length)]}!`,
      );
    }
  }
}

let stevenJ = new Student({ name: 'Steven', age: 22 });
stevenJ.grades.set('Math', 10);
stevenJ.dance();
console.log(stevenJ);
console.log(`stevenJ's interestLevel is: ${stevenJ.interestLevel}`);

```




###### tags: `Javascript`