[英]JS call static method from class
我有一個帶有靜態方法的類:
class User {
constructor() {
User.staticMethod();
}
static staticMethod() {}
}
對於靜態方法,是否有與 this 等效的方法(即在沒有實例的情況下引用當前類)?
this.staticMethod()
所以我不必寫類名:“用戶”。
來自 MDN 文檔
靜態方法調用直接在類上進行,不能在類的實例上調用。 靜態方法通常用於創建實用程序函數。
有關更多信息,請參閱=> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static
你可以做這樣的事情 => this.constructor.staticMethod());
調用靜態方法。
class StaticMethodCall {
constructor() {
console.log(StaticMethodCall.staticMethod());
// 'static method has been called.'
console.log(this.constructor.staticMethod());
// 'static method has been called.'
}
static staticMethod() {
return 'static method has been called.';
}
}
而不是這個 User.staticMethod() 你可以添加 this.constructor.staticMethod()
static
事物綁定到類而不是實例。 所以你至少必須指定類名。
如果您不想將它們綁定到一個類,請將它們設為全局。
javascript中類的靜態成員被添加為類屬性,您可以使用代碼查看列表
console.log(Object.getOwnPropertyNames(PaymentStrategy));
和訪問成員只是
const memberFun = PaymentStrategy["memberName"];
//if member is a function then execute
memberFun();
//or
memberFun(data);
例子:
class PaymentStrategy{
static Card(user){
console.log(`${user} will pay with a credit card`);
}
static PayPal(user){
console.log(`${user} will pay through paypal`);
}
static BKash(user){
console.log(`${user} will pay through Bkash`);
}
}
export default PaymentStrategy;
import PaymentStrategy from "./PaymentStrategy";
class Payment{
constructor(strategy = "BKash"){
this.strategy = PaymentStrategy[strategy];
console.log(Object.getOwnPropertyNames(PaymentStrategy));
}
changeStrategy(newStratgey){
this.strategy = PaymentStrategy[newStratgey];
console.log(`***Payment Strategy Changed***`);
}
showPaymentMethod(user){
this.strategy(user);
}
}
export default Payment;
```
```
import Payment from "./Payment"
const strategyPattern = (()=>{
const execute = ()=>{
const paymentMethod = new Payment();
paymentMethod.showPaymentMethod("Suru");
paymentMethod.showPaymentMethod("Nora");
paymentMethod.changeStrategy("PayPal");
paymentMethod.showPaymentMethod("Rafiq");
}
return{
execute:execute
}
})();
export {strategyPattern}
```
@Rohith KP 的答案簡而言之就是解決方案。
如果你想理解它,你需要了解什么是 JavaScript 類“幕后”。
這是在 ES6 之前創建類的方式:
// This is a constructor function that initializes new Range objects.
// Note that it does not create or return the object. It just initializes this.
function Range(from, to) {
// Store the start and end points (state) of this new range object.
// These are noninherited properties that are unique to this object.
this.from = from;
this.to = to;
}
// All Range objects inherit from this object.
// Note that the property name must be "prototype" for this to work.
// Note that the prototype property is the property of the Range function
Range.prototype = {
// create some methods
// Return true if x is in the range, false otherwise
// This method works for textual and Date ranges as well as numeric.
includes: function(x) { return this.from <= x && x <= this.to; },
// A generator function that makes instances of the class iterable.
// Note that it only works for numeric ranges.
[Symbol.iterator]: function*() {
for( let x = Math.ceil( this.from); x <= this.to; x ++) yield x;
},
// Return a string representation of the range
toString: function() { return "(" + this.from + "..." + this.to + ")"; }
};
// Here are example uses of this new Range class
let r = new Range(1,3);
// r inherits from Range.prototype
r.includes(2) // = > true: 2 is in the range
r.toString() // = > "(1...3)"
[...r] // => [1, 2, 3]; convert to an array via iterator
因此,類本質上是一個函數,它是其原型對象的公共接口(構造函數)。
let F = function() {}; // This is a function object.
let p = F.prototype; // This is the prototype object associated with F.
let c = p.constructor; // This is the function associated with the prototype.
c === F // true
重要的是要理解本示例中定義的類與 ES6 類的工作方式完全相同。 在語言中引入“class”關鍵字並沒有改變 JavaScript 基於原型的類的基本性質。
靜態方法
靜態方法被定義為構造函數的屬性而不是原型對象的屬性。
static parse(s) {
let matches = s.match(/^\((\d+)\.\.\.(\d+)\)$/);
if (!matches) {
throw new TypeError(`Cannot parse Range from "${s}".`)
}
return new Range(parseInt(matches[1]), parseInt(matches[2]));
}
這段代碼定義的方法是Range.parse(),而不是Range.prototype.parse(),你必須通過構造函數調用它,而不是通過實例:
let r = Range.parse('(1...10)'); // Returns a new Range object
r.parse('(1...10)'); // TypeError: r.parse is not a function
您有時會看到稱為類方法的靜態方法,因為它們是使用類/構造函數的名稱調用的。 使用該術語時,是將類方法與在類的實例上調用的常規實例方法進行對比。 因為靜態方法是在構造函數上而不是在任何特定實例上調用的,所以在靜態方法中使用this關鍵字幾乎沒有任何意義。
資料來源:弗拉納根,大衛。 JavaScript:權威指南。
在@Ninjaneer 接受的答案中:
class StaticMethodCall { constructor() {
console.log(StaticMethodCall.staticMethod());
// 'static method has been called.'
console.log(this.constructor.staticMethod());
// 'static method has been called.' }
static staticMethod() {
return 'static method has been called.'; } }
this.constructor.staticMethod()
將拋出錯誤,因為在構造函數中訪問this
之前必須調用超級構造函數。
假設你解決了前面提到的這個問題,沒有雙關語,我認為調用this.constructor.staticMethod()
的唯一好處是你不依賴於類的名稱——如果它發生了變化。 但是,這種好處可能微不足道,因為它只會從類內部進行的靜態方法調用中受益。 外部進行的靜態方法調用必須是像StaticMethodCall.constructor.staticMethod()
這樣的東西,這違背了目的並且看起來很傻。
總之:
如果您打算在類之外使用靜態方法,我肯定會堅持使用 StaticMethodCall.staticMethod(),因為它更慣用和簡潔。
如果您只打算在類中使用靜態方法,那么使用this.constructor.staticMethod()
可能是可以的,但它可能會混淆其他開發人員並將他們帶回此頁面:-)
我剛剛遇到了一個類似的問題(引用超級靜態方法),在這里留下一個答案,以防其他人覺得它有用。
本質上,解決方案是將類本身傳遞給靜態方法。 例如:
class Foo {
static greet(Type) {
return `Hello, ${Type.name()}`
}
static name() {
return 'foo'
}
}
class Bar extends Foo {
static name() {
return 'bar'
}
}
現在你可以打電話
Bar.greet(Bar) // returns 'Hello, bar'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.