簡體   English   中英

從類靜態方法調用 ES6 類構造函數

[英]Calling ES6 class constructor from class static method

我正在嘗試在 JS ES6 類中實現單例模式。 這是我到目前為止所寫的:

let instance;

export class TestClass{

    constructor(){
        if(new.target){
            throw new Error(`Can't create instance of singleton class with new keyword. Use getInstance() static method instead`);
        }
    }
    testMethod(){
        console.log('test');
    }
    static getInstance(){
        if(!instance) {
            instance = TestClass.constructor();
        }

        return instance;
    }
}

但是,當我調用靜態方法TestClass.getInstance() ,我沒有得到類對象的實例,我得到了

ƒ anonymous() {

}

函數,無需訪問 testMethod。 我在我的代碼中找不到錯誤 - 將不勝感激。

TestClass是構造函數。 TestClass.constructor是內置的Function ,它在調用時構造一個新的空函數(您正在記錄的內容)。

TestClass構造函數也可以作為TestClass.prototype.constructor訪問,這可能是你的意思:

static getInstance(){
    if (!instance) {
        instance = TestClass.prototype.constructor();
    }
    return instance;
}

這當然會拋出一個異常,你不能在沒有new情況下調用class構造函數。

您還應該簡化為new TestClass 或者甚至更好,如果你想支持子類化, new this - 注意靜態方法中的this指的是類(構造函數)本身。

我正在嘗試在 JS ES6 類中實現單例模式

請不要。 單身人士是不好的做法。 如果您的類沒有任何狀態,並且無論如何只有一個實例,請不要使用class 隨便寫

export function testMethod() {
    console.log('test');
}
// Yes, that's the whole file!

如果你堅持懶惰地構建模塊,我會推薦

let instance;
/*default*/ export function getInstance() {
    return instance || (instance = { // use a simple object literal
        testMethod(){
            console.log('test');
        }
    });
}

也就是說,如果你堅持要創建一個“私有”構造函數,我會傳遞一個令牌:

const internal = Symbol("creation token for TestClass");
export class TestClass {
    constructor(token) {
        if(token !== internal) {
            throw new Error("Please use the TestClass.getInstance() static method instead");
        }
    }
    …
    static getInstance(){
        return new TestClass(internal); // make sure not to call `this`, otherwise subclassing could leak the token
    }
}

但你永遠不應該真正需要它。

您還沒有創建 TestClass 的實例,您只是將您的instance變量分配為TestClass的構造函數。

如果需要,我通常會像這樣創建單身人士:

class TestClass {
  constructor() {

  }

  testMethod() {

  }
}

const instance = new TestClass();

export default instance;

問題是Class constructors cannot be invoked without 'new' ES6 Class constructors cannot be invoked without 'new' ——你的new.target測試是多余的。 如果您想保留 Class 語法,您可以執行以下操作以確保只有您的模塊能夠創建該類:

 let instance; let creating = false; class TestClass{ constructor(key) { if(!creating) { throw new Error(`Can't create instance of singleton class with new keyword. Use getInstance() static method instead`); } } testMethod() { console.log('test'); } static getInstance() { if(!instance) { creating = true; instance = new TestClass(); creating = false; } return instance; } } const theInst = TestClass.getInstance(); theInst.testMethod();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM