# 類別 Classes class 是 JavaScript 中的一種語言結構,它在 ECMAScript 6 (ES6) 中引入,用於更方便地創建和管理物件及其相關的行為。通過 class,JavaScript 的面向對象編程變得更具結構性和可讀性,同時也提供了繼承和多態性等高級面向對象編程特性。 以下是關於 JavaScript `class` 的一些重要概念和用法: 1. **定義類別**:使用 `class` 關鍵字來定義一個類別。例如: ```javascript class Person { constructor(name, age) { this.name = name; this.age = age; } sayHello() { console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`); } } ``` 在上面的例子中,我們定義了一個 `Person` 類別,它具有 `constructor` 构造函式和 `sayHello` 方法。 2. **建立物件實例**:使用 `new` 關鍵字來實例化一個類別,創建物件的實例: ```javascript const person1 = new Person('Alice', 30); const person2 = new Person('Bob', 25); ``` 這樣我們就創建了兩個 `Person` 物件的實例,`person1` 和 `person2`。 3. **建構函式**:`constructor` 是一個特殊的方法,用於初始化類別的屬性。當使用 `new` 關鍵字創建物件實例時,將自動調用 `constructor` 方法。在上面的例子中,`constructor` 用於初始化 `name` 和 `age` 屬性。 4. **方法**:類別可以包含方法,這些方法可以在物件實例上調用。在上面的例子中,我們定義了 `sayHello` 方法,可以用於顯示該人的資訊。 5. **繼承**:使用 `extends` 關鍵字可以創建一個子類別,從父類別繼承屬性和方法。例如: ```javascript class Student extends Person { constructor(name, age, studentId) { super(name, age); this.studentId = studentId; } study() { console.log(`${this.name} is studying with student ID ${this.studentId}.`); } } ``` 在這個例子中,`Student` 類別繼承了 `Person` 類別的屬性和方法,並添加了自己的 `study` 方法。 6. **super**:`super` 用於調用父類別的 `constructor` 方法或其他方法。在子類別的建構函式中,您可以使用 `super` 來訪問父類別的屬性或調用其方法。 7. **靜態方法**:您可以定義靜態方法,這些方法不依賴於特定物件實例,而是直接與類別關聯。靜態方法使用 `static` 關鍵字定義。 ```javascript class MathUtil { static add(a, b) { return a + b; } } const result = MathUtil.add(5, 10); // 使用靜態方法 ``` ## 相關練習 ### LeetCode 2726 Calculator with Method Chaining 設計一個計算器類別 Design a Calculator class. 該類應提供加、減、乘、除和求冪的數學運算。 它還應該允許使用方法鏈接執行連續操作。 Calculator 類構造函數應該接受一個數字作為結果的初始值。 The class should provide the mathematical operations of addition, subtraction, multiplication, division, and exponentiation. It should also allow consecutive operations to be performed using method chaining. The Calculator class constructor should accept a number which serves as the initial value of result. 您的計算器類應該具有以下方法: Your Calculator class should have the following methods - add - 此方法將給定的數值添加到結果中並返回更新的計算器。 This method adds the given number value to the result and returns the updated Calculator. - minus - 此方法從結果中減去給定的數值並返回更新後的計算器。 This method subtracts the given number value from the result and returns the updated Calculator. - multiply - 此方法將結果乘以給定數值並返回更新後的計算器。 This method multiplies the result by the given number value and returns the updated Calculator. - divide - 此方法將結果除以給定的數值並返回更新後的計算器。 如果傳遞的值為 0,則應拋出錯誤“不允許除以零”。 This method divides the result by the given number value and returns the updated Calculator. If the passed value is 0, an error "Division by zero is not allowed" should be thrown. - power - 此方法將結果計算給定數值的冪並返回更新後的計算器。 This method raises the result to the power of the given number value and returns the updated Calculator. - getResult - 此方法返回結果。 This method returns the result. 與實際結果相差 10-5 以內的解被認為是正確的。 Solutions within 10-5 of the actual result are considered correct. #### 解決方案 依照題目寫出創建類別即可,重點在建構函式內初始化屬性,他會儲存result的值, 之後運算的時候都會訪問result值進行鍊式計算與更新,再返回實例對象`this`。 ```javascript class Calculator{ //建構函式 初始化屬性result=參數的val值 constructor(val){ this.result = val; } //加法 add(val){ this.result += val; return this; } //減法 subtract(val){ this.result -= val; return this; } //乘法 multiply(val){ this.result *= val; return this; } //除法 divide(val){ if (val == 0){ throw new Error("Division by zero is not allowed"); } this.result /= val; return this; } //指數運算(幂) power(val){ this.result **= val; return this; } //取得結果 getResult(val){ return this.result; } } ``` ### LeetCode 2695 Array Wrapper 創建一個類“ArrayWrapper”,在其構造函數中接受整數數組。 這個類應該有兩個特點: Create a class `ArrayWrapper` that accepts an array of integers in its constructor. This class should have two features: - 當使用“+”運算符將此類的兩個實例相加時,結果值是兩個數組中所有元素的總和。 When two instances of this class are added together with the `+` operator, the resulting value is the sum of all the elements in both arrays. - 當在實例上調用“String()”函數時,它將返回一個用括號括起來的逗號分隔字符串。 例如,“[1,2,3]”。 When the `String()` function is called on the instance, it will return a comma separated string surrounded by brackets. For example, `[1,2,3]`. #### 解決方案 1. 創建類別與方法 ```javascript class ArrayWrapper { constructor(nums) { this.nums = nums; } valueOf() { //兩個實例相加處理 方法 } toString() { //字串相加處理 方法 } } ``` 2. 兩個實例相加處理 方法 ```javascript class ArrayWrapper { constructor(nums) { this.nums = nums; } valueOf() { let sum = 0; //this.nums=[[1,2],[3,4]] for (let i = 0; i < this.nums.length; i++) { for (let j = 0; j < this.nums[i].length; j++){ sum += this.nums[i][j]; } } return sum; } toString() { //字串相加處理 方法 } } ``` 3. 字串相加處理 方法 ```javascript class ArrayWrapper { //this.nums=[[1,2],[3,4]] constructor(nums) { this.nums = nums; } valueOf() { let sum = 0; for (let i = 0; i < this.nums.length; i++) { for (let j = 0; j < this.nums[i].length; j++){ sum += this.nums[i][j]; } } return sum; } toString() { let str = '['; for (let i = 0; i < this.nums.length; i++) { str += this.nums[i]; if (i !== this.nums.length - 1) { str += ','; } } str += ']'; return str; } } ``` 💡 更簡潔的方法 - valueOf() - 使用Array.flat(1); 將多維陣列平坦化為一維陣列 - 使用Array.reduce(); 相加所有元素 - toString() - 使用Array.join(,) 把所有的元素中間用,隔開並組合成字串 ```javascript class ArrayWrapper { //this.nums=[[1,2],[3,4]] constructor(nums) { this.nums = nums; } valueOf() { const flattenArray = this.nums.flat(1); return flattenArray.reduce((sum, num) => sum + num, 0); } toString() { return `[${this.nums.join(',')}]`; } } ``` testcase1 ```javascript let nums1 = [[1,2],[3,4]] let ex1 = new ArrayWrapper(nums1); console.log(ex1.valueOf()); // 10 ``` testcase2 ```javascript let nums2 = [[23,98,42,70]] let ex2 = new ArrayWrapper(nums2); console.log(ex2.toString()); //[23,98,42,70] ``` testcase3 ```javascript let nums3 = [[],[]] let ex3 = new ArrayWrapper(nums3); console.log(ex3.valueOf()); // 0 ```