#javascript #node.js
#javascript #node.js
Вопрос:
Как я могу инициализировать статическую переменную в module.exports = class
в node.js .
В принципе, чего я пытаюсь достичь, так это того, что если StaticVariable
равно null, я получу данные из файла json. Затем сохраните ее в StaticVariable
.
module.exports = class Config {
static fetch() {
if ( StaticVariable === null ) {
const fs = require('fs');
const data = fs.readFileSync('./config.json');
const config = JSON.parse(data);
StaticVariable = config;
}
return StaticVariable;
}
}
Функция fetch()
будет вызываться несколько раз, поэтому нет необходимости в readFileSync
каждом вызове.
Комментарии:
1. Какая проблема у вас с этим кодом, кроме того, что вы не определили переменную staticVariable? Класс только для статики является антипаттером. Является ли fetch единственным элементом?
2. Я сделал
fetch()
статичным , потому что не хочуnew Config
. @estus3. Это не объясняет, зачем вам нужен класс. Является ли fetch единственным элементом?
4. Если вы спрашиваете, является ли fetch единственной функцией, это не так.. Там будет
new
,update
и т.д. и не будет статической функции. @estus5. Пожалуйста, обновите вопрос всем соответствующим кодом и примером того, как вы используете Config. Должно ли быть несколько экземпляров? То, что у вас здесь есть, похоже, является проблемой XY, которую можно было бы решить лучшим способом. Обязательно ли иметь lazy
fetch
? Вы могли бы просто сделатьexports.config = require('./config.json')
в верхней части модуля
Ответ №1:
Класс только для статики является антипаттером в JavaScript, потому что класс никогда не создается.
В случае, если необходимо иметь метод, который лениво загружает файл JSON, можно использовать обычный объект. В области видимости модуля уже есть такой объект, module.exports
:
const fs = require('fs');
let StaticVariable;
exports.fetch = () => {
if ( StaticVariable == undefined ) { // not "=== null"
const data = fs.readFileSync('./config.json');
const config = JSON.parse(data);
StaticVariable = config;
}
return StaticVariable;
}
Возможно, нет необходимости разбирать ее вручную, потому что это может быть обработано require('./config.json')
однострочно и с более согласованными относительными путями.
В случае, если файл JSON можно быстро загрузить, это можно упростить до:
exports.config = require('./config.json');
Если есть необходимость в Config
классе и он должен получить доступ к объекту конфигурации, он может ссылаться на него, например:
exports.Config = class Config {
constructor() {
this.config = deepClone(exports.config);
}
modify() {
// modify this.config
}
};
Ответ №2:
Я могу придумать несколько способов достичь того, о чем вы просите.
Сохранение ее в глобальной переменной
//initialise it here
var StaticVariable = null;
//however if you initialise it here, it makes more sense to just load it once
const fs = require('fs');
const data = fs.readFileSync('./config.json');
const config = JSON.parse(data);
StaticVariable = config;
module.exports = class Config {
static fetch() {
return StaticVariable;
}
}
Или просто используйте require. Require сделает то же самое, что вы хотите сделать. Он прочитает файл config.json, попытается проанализировать его как действительный json и сделает это только один раз.
module.exports = class Config {
static fetch() {
return require('./config.json');
}
}
Ответ №3:
Начиная с (узла 15.2.1) ES2020, поддерживаются статические поля частного класса. Таким образом, отныне статический класс не может быть антишаблоном, и вы можете создать экземпляр класса, используя новые ключевые слова. ссылка: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static
module.exports = class Config {
static #StaticVariable = null;
static fetch() {
if ( StaticVariable === null ) {
const fs = require('fs');
const data = fs.readFileSync('./config.json');
const config = JSON.parse(data);
StaticVariable = config;
}
return StaticVariable;
}
}
Где # sign означает private больше ссылок можно найти вhttps://node.green , но все же самый простой способ описан в других ответах
exports.config = require('./config.json');