Я нашел разные темы, объясняющие, как создать синглтон, но ни один из них не работал для меня. Это пример, взятый из этой публикации
export default class Credentials {
static myInstance = null;
_userID = "";
static getInstance() {
if (myInstance == null) {
myInstance = new Credentials();
}
return myInstance;
}
getUserID() {
return this._userID;
}
setUserID(id) {
this._userID = id;
}
}
когда я вызываю Credentials.getInstance()
я получаю предупреждение
Не удается найти переменную myInstance
JS не имеет неявного поиска в поле, как статически скомпилированные языки. Вам нужно явно искать переменные в классе:
class Credentials {
static myInstance = null;
static getInstance() {
if (Credentials.myInstance == null) {
Credentials.myInstance = new Credentials();
}
return Credentials.myInstance;
}
}
Будьте осторожны с этим подходом, поскольку это не поистине одноэлемент, потому что JS не имеет надлежащей инкапсуляции класса.
Вы можете легко изменить экземпляр:
Credentials.myInstance = 'something else';
Правильный синглтон с инкапсуляцией должен быть реализован через закрытие:
const Credentials = (() => {
let myInstance = null;
return class Credentials {
static getInstance() {
if (myInstance == null) {
myInstance = new Credentials();
}
return myInstance;
}
}
})()
Я думаю, что самым простым и понятным решением будет "синглтонная модель ES6" (не уверен, есть ли официальное название этого шаблона).
Вы экспортируете экземпляр по умолчанию, и везде, где вы его импортируете, вы получаете тот же экземпляр. Это зависит от того, что модуль требует кэширования.
Вы бы создали свой класс и экспортировали его так:
class Credentials {
constructor() {
this._userID = "";
}
get userID() {
return this._userID;
}
set userID(userID) {
this._userID = userID;
}
}
export default new Credentials();
Где бы вы его не импортировали, вы получаете тот же экземпляр:
import credentials from './credentials';
Этого должно быть достаточно для любого экземпляра одной тонны в JS.
Теперь, где бы вы его не импортировали, будет использоваться тот же самый экземпляр. Вы можете перекрестно проверить, добавив дату внутри класса и доступ к ней в разных местах, где вы импортировали это.
import { SomeClass } from 'some-class'
let singletonInstance;
if (!singletonInstance) {
singletonInstance = new SomeClass();
// singletonInstance.time = new Date();
}
export default singletonInstance;
Затем импортируйте его, используя
import singletonInstance from './above-code-file'