2012-06-14 13 views
11

Si consideri il seguente script:Come posso definire condizionatamente una funzione in javascript?

if (false)​ { 
    function foo() { 
     alert("FOO"); 
    } 
} 
foo(); // alerts "FOO" 

Come si può vedere, la funzione foo è definita e funziona anche se la condizione per la if fallisce.

Il motivo per cui voglio farlo è che sto sviluppando un'estensione per InDesign e ho creato uno script chiamato utilities.jsx che contiene varie funzioni utilizzate in altri script. In tutti gli script che richiedono queste funzioni, uso semplicemente:

app.doScript(File(scriptsFile.parent.fsName + "/t_utilities.jsx"), ScriptLanguage.JAVASCRIPT); 

che definisce tutte le funzioni di cui ho bisogno e quindi posso usarle. Ora, poiché questo script verrà chiamato più volte da vari file in un ordine imprevedibile (l'utente decide), ho pensato che potrei definire le funzioni solo se non sono state definite prima (se utilities.jsx non è ancora stato eseguito) . Un po 'come require_once in php.

Stavo pensando a qualcosa di simile a quanto segue, ma che non funziona come le funzioni sono definite ogni volta che lo script viene eseguito: `

var utilitiesHasRun; 
if (utilitiesHasRun !== true) { 
    // define all the functions 
    // ... 
    utilitiesHasRun = true; 
} 

ci sono altre opzioni?

+2

Il primo snippet di codice non è tecnicamente valido perché le dichiarazioni di funzione non sono consentite all'interno dei blocchi. Funziona solo perché tutti i principali browser implementano estensioni alle specifiche ECMAScript per gestire questo caso. –

+0

E per continuare il commento di @ TimDown, il tuo primo snippet genererà effettivamente un SyntaxError se fa parte del codice di modalità rigoroso. –

risposta

6

Per assicurare la funzione non è stato definito in precedenza, l'uso:

if (typeof yourFunctionName == 'undefined') { 
    yourFunctionName = function(params) { 
    // your code here 
    }; 
} 
+0

Questo genera un errore se 'yourFunctionName' non è definito inizialmente. Tuttavia, un 'typeof yourFunctionName == 'undefined'' funzionerebbe. –

+0

@JuanMendes Punto preso e corretto. – Sirko

15

È possibile farli funzionano espressioni al posto della funzione dichiarazioni:

if (false)​ { 
    var foo = function() { 
     alert("FOO"); 
    }; 
} 
foo(); //TypeError: undefined is not a function 

Si noti che nel codice sopra riportato, foo è ancora accessibile, anche se la condizione è risultata falsa. Questo perché le dichiarazioni (sia funzione che variabile) vengono issate nella parte superiore dell'ambito in cui sono dichiarate. Tuttavia, gli incarichi si verificano nel punto in cui appaiono.

Quello che il codice di cui sopra è effettivamente facendo è questo:

var foo; //No assignment, foo is undefined 
if (false)​ { 
    foo = function() { 
     alert("FOO"); 
    }; 
} 
foo(); //TypeError: undefined is not a function 

Attenzione - espressioni funzione chiamata sono ancora issate in Internet Explorer 8 e al di sotto (questo un bug in IE). Ovviamente questo è solo un potenziale problema se hai bisogno di supportare i vecchi browser.

+1

+1: molto conciso. Non mi ero reso conto che le dichiarazioni di funzione erano ancora state issate, pensavo fossero solo espressioni di funzione, ma ora vedo la sottile differenza! –

+0

+1 Ahh, sollevamento. Grazie per aver spiegato questo. Ho scelto la risposta di Sirko in quanto non produce un errore, ma la tua soluzione funziona anche se si blocca semplicemente la chiamata a foo ('foo()') in un blocco try, evitando che l'errore rotti lo script. – Shawn

+0

Apparentemente un bug in firefox –

3

È possibile utilizzare i puntatori di funzione per riassegnare la funzione in base alle esigenze.

var myFunctionPointer = function { alert("Default"); }; 
if (condition) { 
    myFunctionPointer = function { alert("true"); }; 
} 
else { 
    myFunctionPointer = function { alert("false"); }; 
} 
myFunctionPointer(); 
0

solito creare un'API completa sulla base di una funzione che restituisce un oggetto contenente metodi che sono infine chiamare al minore JS funzioni. Le estensioni possono interagire con i file JS con una classe incorporata. Penso di averti dato il link al libro di cucina.Che cosa si può fare è dichiarare un oggetto in AS3 e verificare la presenza di alcune proprietà come:

public var jsAPI:Object = {}; 

il codice js sarebbe

var jsAPI = function() { 
    return { 
     hasBeenLoaded:false, 
     myMethod1:function(){}, 
    } 
} 

Poi, se è necessario utilizzare una funzione JS in AS3, è può controllare qualche bandiera come:

if (jsAPI.hasBeenLoaded){ … } 
else { //loads the API via new API() } 
Problemi correlati