2015-01-03 5 views
11

я просматривал исходный код здесь: http://js-dos.com/games/doom2.exe.html и заметил несколько вещей:Какова цель этого условного условного выражения?

if (typeof Module === 'undefined') 
{ 
    Module = eval('(function() {try { return Module || {} } catch(e) { return {} }})()'); 
} 
  • Функция модуля определяются с помощью встроенного сценария тега
  • Это позже снова объявлено с var в другом инлайн тег, на этот раз он проверяет, существует ли модуль.

Моим вопрос: Какой смысл объявлять модуль с функцией самостоятельной вызывающей, если это будет только попытаться вернуть модуль снова? Разве это уже не доказано, что его нет? Почему бы просто не объявить модуль как {}?

+4

Этот код находится в github в проекте emscripten. Он был добавлен в эту фиксацию: https://github.com/kripken/emscripten/commit/22d510338239c1cf33136392c77a9b3d7d2ce2bc. Они отошли от явного объявления в оператор eval, но коммит commit isn; t ясно почему! Я добавил emscripten в качестве тега, тогда кто-то из проекта или кто его знает, может заметить и помочь. – sifriday

ответ

5

typeof Module может быть не определено, если модуль является локальной переменной, которая содержит undefined. Этот код предназначен для поддержки нескольких случаев, модуль может быть локальным или глобальным и определен или не определен. Мы хотим избежать загрязнения глобальной области, поэтому мы не просто делаем Module = ..., если он не определен.

Во-первых, обычный случай - это код, генерируемый emscripten, в глобальном масштабе. В этом случае модуль может или не может быть определен и может быть локальным, но все же undefined, поэтому нам необходимо обрабатывать оба.

Во-вторых, код emscripten может быть просто модулем, как игра, в которой используется ammo.js. В этом случае использование является

function Ammo(Module) { 
    // emscripten-generated code, uses the Module 
    return something; 
} 

так Модуль в этом случае является локальной функцией, заданная парами уже определенных для нас.

Мы не можем просто объявить var Module, потому что это означает, что модуль является локальной переменной. Так что нам нужно eval. Для eval нам нужна функция, которая возвращает значение, потому что нам нужен try-catch. Try-catch использует Module, и будет выходить, если модуль не является локальным (независимо от того, содержит ли он undefined или нет), что и есть то, что мы хотим.

Возможно, этот код можно было бы упростить!

+2

Поскольку вы не упомянули об этом, для записи: ** Алон является автором этих строк. ** –

+2

Комбинация github и SO очень впечатляет и полезна для того, чтобы иметь возможность ответить на этот вопрос и присоединиться это до фиксации, а затем автора, который может ответить на вопрос. – sifriday

Смежные вопросы