Поднятая локальная переменная, маскирующая глобальную переменную?

Наткнулся на странное поведение в node. У меня есть скомпилированная программа emscripten, которую я хочу использовать в качестве библиотеки. emscripten использует переменную Module для управления поведением во время выполнения и генерирует код, подобный ./lib/g.js ниже. В браузере Module имеет правильный псевдоним от глобального, определенного в index.js, до локального var в ./lib/g.js. Однако в node этого, похоже, нет. Конструкция: var Module = Module || {}; стирает мой глобальный Module.

index.js:

global.Module = { name: 'Module' };
var g = require ( './lib/g.js' );

./lib/g.js:

console.log ( 'Module: ', Module );

var Module = Module || {};

Выход node index.js:

Module:  undefined

Я предполагаю, что в g.js Module поднимается и разыменовывается только в локальной области видимости, маскируя глобальную версию (в global.Module). Может ли кто-нибудь предложить обходной путь?

Эту проблему можно решить, отредактировав созданный emscripten код для использования var Module = global.Module || {}. Хотя это возможный обходной путь, я бы не стал редактировать код, сгенерированный emscripten.


person Daniel Blezek    schedule 15.11.2014    source источник
comment
Если есть Module, определенный в более высокой области, то var Module = Module || {} просто создаст для него псевдоним в этой области. Доступ к свойствам Module будет прекрасно работать для доступа к свойствам переменной с более высокой областью действия.   -  person jfriend00    schedule 15.11.2014
comment
@jfriend00: это ожидаемое поведение, но в приведенном примере это не сработало. Работает корректно в браузере, но не в node. Не удалось найти правила области видимости переменных для node, охватывающие этот случай.   -  person Daniel Blezek    schedule 16.11.2014
comment
Похоже, emscripten ожидает, что его выходные скрипты будут выполняться в глобальной области, а не в области модуля. Вы можете попробовать глобальную оценку, если не хотите редактировать код.   -  person Bergi    schedule 16.11.2014
comment
Мне кажется, что у вас есть конфликт между глобальным Module, который использует emscripten, и глобальным Module, который использует node. Возможно, они оба пытаются определить/использовать одно и то же, или один из них переопределяет и переопределяет другой.   -  person jfriend00    schedule 16.11.2014


Ответы (2)


Вы можете взглянуть на использование rewire

var rewire = require("rewire");
var g = rewire("./lib/g");
g.__set__("Module", {name: "Module"});
person Peter Lyons    schedule 16.11.2014

Может ли кто-нибудь предложить обходной путь?

Просто удалите ключевое слово var.

person Peter Lyons    schedule 15.11.2014
comment
Отредактировал вопрос для ясности. Чего я пытаюсь избежать, так это редактирования кода, сгенерированного emscripten. Изменение сгенерированного кода не всегда является хорошей идеей. Спросите emscripten сообщество напрямую. - person Daniel Blezek; 16.11.2014