了解 JS 類別中原型方法(static)和靜態方法(prototype)之間的區別
關於 static methods & prototype methods 的使用時機與差異
前言
今天刷題刷到 988. Smallest String Starting From Leaf,要在二元樹中計算字典順序最小的字串, 其中一個操作是要將 node.val 轉換成字串才能進行字典大小比較,所以用到 String.fromCharCode() 來進行轉換, 也順便想起 ''.charCodeAt() 可以將字串轉換成 Unicode 碼位,因為這兩個方法常常配合使用, 也因為之後要準備面試,也嘗試著自己解釋下兩者的差異,發現沒有辦法一次就解釋得很清楚, 所以做了些筆記紀錄下兩者的差異和使用時機加深印象。
靜態方法(Static)跟原型方法(Prototype)的差別
靜態方法和原型方法在使用方式和作用域上有所不同,。
- 靜態方法(Static Methods):
- 靜態方法屬於類(class)本身,而不是類的實例(Instance),因此在使用時不需要創建類的實例。
- 可以通過類本身直接調用,例如 String.fromCharCode(65)。 'A'
- 靜態方法通常用於提供與類相關的工具函數或工廠函數,而不是操作實例本身。
- 原型方法(Prototype Methods):
- 原型方法屬於類的原型(Prototype),可以在類的每個實例上調用。
- 原型方法通常用於定義對實例操作的方法,例如 "".charCodeAt(0) 是針對字符串實例的方法。
要設計一個 class 時,該如何判斷要將功能做成 Static methods 還是 Prototype methods
可以由下面幾點因素來思考
是否需要訪問實例的狀態:原型方法可以訪問 this 關鍵字來引用當前實例。
是否與類的實例直接相關:靜態方法可以直接由類調用,而不需要實例。
是否需要在實例化之前就可以使用:這樣可以避免不必要的實例化。
是否需要在子類中覆蓋:
以 String.fromCodeAt 和 ''.charCodeAt() 為例
- String.fromCharCode 的使用與特定字串實例無關,可以直接由 String 類調用,並根據傳入的 Unicode 碼點返回對應的字符。 傳入值也不指定要特定字串(允許數字或字串)。所以設計成 Static methods。
- ''.charCodeAt() 的使用與特定字串實例相關,是用來獲取特定字串的 Unicode 碼點。使用錢要先訪問實例內部的字符,因此設計成原型方法。
嘗試設計一個信用卡 Class Card {}
假設要設計一個信用卡 Class Card ,以下方法哪些適合設計成 Static methods, 哪些設計成 Prototype methods
適合設計成 Static methods (與信用卡實例的狀態無關者)
- validateCardNumber(cardNumber): 驗證信用卡號是否有效。
- generateCardNumber(cardType): 生成指定類型的信用卡號。
- getCardType(cardNumber): 根據信用卡號獲取信用卡類型。
適合設計成 Prototype methods (須先進行實例才能進行操作者)
- charge(amount): 用信用卡支付特定金額。
- getBalance(): 獲取信用卡當前餘額。
- makePayment(amount): 用戶對信用卡進行還款。
class Card {
constructor(location, balance) {
this.location = location;
this.balance = balance;
}
static validateCardNumber(cardNumber) {
return cardNumber.length == 16;
}
getBalance() {
return this.balance;
}
}
class JCB extends Card {
constructor(location, balance, branch, cardNumber) {
super(location, balance); // 調用父類的 constructor,將父類需要的參數傳遞過去。
this.branch = branch;
this.cardNumber = cardNumber;
}
}
let My_JCB_Card = new JCB("Taiwan", 1600, "taipei area", "1111222233334444");
console.log(My_JCB_Card.location); // 'Taiwan'
console.log(My_JCB_Card.branch); // 'taipei area'
console.log(Card.validateCardNumber(My_JCB_Card.cardNumber)); // true
console.log(My_JCB_Card.getBalance()); // 1600
- 前言
- 靜態方法(Static)跟原型方法(Prototype)的差別
- 要設計一個 class 時,該如何判斷要將功能做成 Static methods 還是 Prototype methods
- 嘗試設計一個信用卡 Class Card {}