2015-01-03 14 views
11

stavo dando un'occhiata al codice sorgente qui: http://js-dos.com/games/doom2.exe.html e ho notato un paio di cose:Qual è lo scopo di questa condizione di valutazione?

if (typeof Module === 'undefined') 
{ 
    Module = eval('(function() {try { return Module || {} } catch(e) { return {} }})()'); 
} 
  • La funzione del modulo viene definito con un tag script inline
  • E 'poi dichiarato di nuovo con var in un'altra linea tag, questa volta controlla se il modulo esiste.

La mia domanda: Qual è il punto di dichiarare Modulo con una funzione che esegue il richiamo di auto se si cercherà solo per tornare di nuovo il modulo? Non è già stato provato che non esiste? Perché non dichiarare semplicemente il modulo come {}?

+4

Questo codice è in github nel progetto emscripten. È stato aggiunto in questo commit: https://github.com/kripken/emscripten/commit/22d510338239c1cf33136392c77a9b3d7d2ce2bc Si sono spostati dalla dichiarazione esplicita all'istruzione eval, ma il messaggio di commit non è chiaro perché! Ho aggiunto emscripten come tag, quindi qualcuno del progetto, o che lo conosce bene, potrebbe individuarlo ed essere in grado di aiutare. – sifriday

risposta

5

typeof Module potrebbe essere indefinito se Module è una variabile locale che capita di contenere undefined. Questo codice è pensato per supportare alcuni casi, il modulo potrebbe essere locale o globale e definito o indefinito. Vogliamo evitare di inquinare l'ambito globale, quindi non facciamo semplicemente Module = ... se non è definito.

In primo luogo, il caso normale è il codice generato da emscripten nell'ambito globale. In questo caso, il Modulo può o non può essere definito, e può essere locale ma comunque undefined, quindi è necessario gestirli entrambi.

In secondo luogo, il codice emscripten può essere solo un modulo, come un gioco che utilizza ammo.js. In tal caso, l'utilizzo è

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

così Module in questo caso è una funzione locale, fornita a titolo param già definito per noi.

Non possiamo semplicemente dichiarare var Module perché ciò significa che Module è una variabile locale. Quindi abbiamo bisogno di valutazione. Per eval, abbiamo bisogno di una funzione che restituisca un valore, perché abbiamo bisogno di un try-catch. Il try-catch utilizza il modulo e genera se il modulo non è locale (indipendentemente dal fatto che contenga o meno undefined), che è esattamente ciò che vogliamo.

E 'possibile che questo codice possa essere semplificato, però!

+2

Dato che non ne parli, per la cronaca: ** Alon è l'autore di quelle linee. ** –

+2

La combinazione di github e SO è potente e utile, per poter rispondere a una domanda come questa e partecipare fino al commit e poi all'autore, che può quindi rispondere alla domanda. – sifriday