Fur*_*man 5 javascript singleton constructor ecmascript-6 es6-class
我正在尝试在 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;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我调用静态方法时TestClass.getInstance(),我没有得到类对象的实例,我得到了
ƒ anonymous() {
}
Run Code Online (Sandbox Code Playgroud)
函数,无需访问 testMethod。我在我的代码中找不到错误 - 将不胜感激。
TestClass是构造函数。TestClass.constructor是 builtin Function,它在调用时构造一个新的空函数(您正在记录的内容)。
该TestClass构造也可以作为访问的TestClass.prototype.constructor,这就是你可能是指:
static getInstance(){
if (!instance) {
instance = TestClass.prototype.constructor();
}
return instance;
}
Run Code Online (Sandbox Code Playgroud)
这当然会抛出一个异常,如果class没有new.
您还应该简化为new TestClass. 或者甚至更好,如果您想支持子类化,请new this注意this在静态方法中是指类(构造函数)本身。
我正在尝试在 JS ES6 类中实现单例模式
请不要。单身人士是不好的做法。如果您的类没有任何状态,并且无论如何只有一个实例,请不要使用class. 写就好了
export function testMethod() {
console.log('test');
}
// Yes, that's the whole file!
Run Code Online (Sandbox Code Playgroud)
如果你坚持懒惰地构建模块,我会推荐
let instance;
/*default*/ export function getInstance() {
return instance || (instance = { // use a simple object literal
testMethod(){
console.log('test');
}
});
}
Run Code Online (Sandbox Code Playgroud)
也就是说,如果你坚持要创建一个“私有”构造函数,我会传递一个令牌:
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
}
}
Run Code Online (Sandbox Code Playgroud)
但你永远不应该真正需要它。