class Foo{
}
var instance: Foo;
export function getFooInstance(){
/* logic */
}
或
export class Foo{
private static _instance;
private constructor(){};
public getInstance(){/* logic */}
}
// Use it like this
Foo.getInstance()
我想确保对象只有一个方法实例?除此之外还有其他任何建议吗?
两者的打字稿游乐场link:
答案 0 :(得分:5)
如果你想在课堂上使用getter,那么它需要是静态的:
export class Foo{
private static _instance;
private constructor(){};
public static getInstance(){/* logic */}
}
问题在于,虽然编译器会强制执行此私有可见性,但在运行时仍然可以绕过它,甚至是无意中,例如有人直接使用javascript。
如果使用模块/命名空间强制执行,则可以完全隐藏它:
使用模块:
export interface IFoo {}
class Foo implements IFoo {}
var instance: Foo;
export function getFooInstance(): IFoo {
/* logic */
return instance;
}
这是你的代码,我只是对IFoo
接口(也是导出的)进行了修改,以便谁获得一个实例将知道接口而不是类。
使用命名空间:
namespace Foo {
export interface IFoo {}
class FooClass implements IFoo {}
const instance = new FooClass();
export function getInstance(): IFoo {
return instance;
}
}
答案 1 :(得分:4)
在JS和TypeScript中,如果你真的只想要一个实例,那么为什么不通过导出一个对象文字来强制执行语言呢?
const Foo = {
doSomething() {
}
}
export default Foo;
IMO,这是遵循KISS,最少量的样板,并且任何人都无法创建多个实例。
话虽如此,你也可以直接导出函数。请记住,模块本身可以作为单身人士。
export function doSomething() {
}
然后导入并希望将其视为可以使用import *的对象。如果函数真的属于对象而不是所有无状态静态函数,我更喜欢第一种方法。
import * as Foo from './Foo';
Foo.doSomething();
答案 2 :(得分:2)
这取决于是否应该有机会为单例类创建新实例。在最后一种情况下,getInstance
可以省略,类构造函数可以作为单例工厂:
class Foo {
private static _instance;
constructor(...args) {
if (Foo._instance) {
return Foo._instance;
}
// if Foo extends non-singleton class or whatever,
// super(...args);
Foo._instance = this;
};
}
任何类的装饰器都可以完成同样的事情,例如:
@singleton
class Foo { ... }
由于存在一些typing problems with TypeScript decorators,因此应在singleton
装饰器中使用自定义继承代码而不是Singleton extends Class
:
function singleton(Class) {
function extend(sub, sup) {
for (var prop in sup)
if (sup.hasOwnProperty(prop))
sub[prop] = sup[prop];
function __() {
this.constructor = sub;
}
__.prototype = sup.prototype;
sub.prototype = new __();
};
const Singleton = <any>function (...args) {
if (Singleton._instance) {
return Singleton._instance;
}
Class.apply(this, args);
Singleton._instance = this;
}
extend(Singleton, Class);
return Singleton;
}
这可能会影响打字,但语法仍然很整洁。