# 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`