Как я могу получить постоянную переменную с глобальным объектом в Nodejs? - PullRequest
0 голосов
/ 05 января 2019

Я хотел получить постоянную переменную с глобальным объектом , чтобы использовать его динамически, но global.myconstant не работает, но global.myvar работает.

λ node
> const myconstant = true
undefined
> global.myconstant
undefined
> var myvar = true
undefined
> global.myvar
true
> global.const
undefined

Что я хочу сделать:

const myconstant = () => { console.log("ok const"); };
var myvariable = () => { console.log("ok var"); };

const watchlist = {
  myconstant: "file1.html",
  myvariable: "file2.html"
};

Object.keys(watchlist).forEach((taskName) => {
  try {
    global[taskName](); //doesn't work with const
  } catch (e) {
    console.error("error", taskName);
  }
});

Фактическая выработка:

error myconstant
ok var

Требуемый вывод:

ok const
ok var

Демонстрация в реальном времени: https://repl.it/repls/SunnyScholarlyPasswords

Как я могу получить константную переменную со строкой? без замены const на var.

Ответы [ 2 ]

0 голосов
/ 05 января 2019

Описанное поведение является естественным для Node REPL, но не для кода, который оценивается в модулях. Переменные в области видимости модуля не попадают в глобальные, потому что они определены в область видимости модуля , это относится как к var, так и к const. Вот что произойдет в модуле Node:

const myconstant = 1;
var myvariable = 2;

console.log(global.myconstant) // undefined
console.log(global.myvariable) // undefined

Причина, по которой это происходит в REPL, заключается в том, что код оценивается в глобальной области видимости. Описанное поведение может быть воспроизведено в области видимости модуля с косвенной eval:

(0, eval)(`
  const myconstant = 1;
  var myvariable = 2;
`);

console.log(global.myconstant) // undefined
console.log(global.myvariable) // 2

Это разница между var и переменными в области блока (const и т. Д.). При определении в глобальной области действия var приводит к определению свойства глобальной переменной (global в узле), тогда как const - нет.

Если целью является определение глобального, оно должно быть определено как свойство:

global.myconstant = 1;
global.myvariable = 2;

Если необходимо определить глобальную переменную, которая не будет переназначена, следует использовать дескриптор (как уже объясняется в другом ответе):

Object.defineProperty(global, 'myconstant', {
  value: 1,
  configurable: false,
  writable: false
});

Использование глобалов для локальных целей обычно не рекомендуется, особенно в таких модульных средах, как Node.

0 голосов
/ 05 января 2019

Только переменные, объявленные с var, неявно присваиваются глобальному объекту. Если вы хотите создать свойство без переназначения, вы должны использовать Object.defineProperty. Например, в браузере, ссылаясь на window вместо global:

Object.defineProperty(
  window,
  'myconstant',
  {
    value: () => { console.log("ok const"); },
    configurable: false
  }
);
var myvariable = () => { console.log("ok var"); };

const watchlist = {
  myconstant: "file1.html",
  myvariable: "file2.html"
};

Object.keys(watchlist).forEach((taskName) => {
  try {
    window[taskName]();
  } catch (e) {
    console.error("error", taskName);
  }
});

// Won't reassign, and will throw an error in strict mode:
window.myconstant = 'foo';
console.log(typeof window.myconstant);

Ключ configurable: false является ключом, но он необязательный - по умолчанию он равен false. Ненастраиваемые свойства не могут быть изменены или удалены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...