Try   HackMD

Javascript Class 類

定義

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

類陳述式

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

類表達式

// 不具名類
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
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);

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

GETTER | SETTER

getter method 是在 class 中沒有帶參數就可以回傳值的方法,可以透過 get 設定;setter method 則是可以透過 = 來對物件賦值,可以使用 set 來設定

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

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


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 來進行繼承創建子類


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