Come si fa a stabilire se una funzione in JavaScript è definita?
Voglio fare qualcosa del genere
function something_cool(text, callback) {
alert(text);
if( callback != null ) callback();
}
Ma mi prende a
la richiamata non è una funzione
errore quando il callback non è definito.
typeof callback === "function"
Tutte le risposte attuali usano una stringa letterale, che preferisco non avere nel mio codice se possibile - questo non (e fornisce un prezioso significato semantico, per l'avvio):
function isFunction(possibleFunction) {
return typeof(possibleFunction) === typeof(Function);
}
Personalmente, provo a ridurre il numero di stringhe in giro nel mio codice ...
Inoltre, mentre sono consapevole che typeof
è un operatore e non una funzione, c'è poco danno nell'uso della sintassi che lo fa apparire come quest'ultimo.
if (callback && typeof(callback) == "function")
Si noti che il callback (di per sé) restituisce false
se è undefined
, null
, 0
o false
. Il confronto con null
è eccessivamente specifico.
Quei metodi per dire se una funzione è implementata falliscono anche se la variabile non è definita, quindi stiamo usando qualcosa di più potente che supporta la ricezione di una stringa:
function isFunctionDefined(functionName) {
if(eval("typeof(" + functionName + ") == typeof(Function)")) {
return true;
}
}
if (isFunctionDefined('myFunction')) {
myFunction(foo);
}
Nuovo su JavaScript Non sono sicuro che il comportamento sia cambiato, ma la soluzione fornita da Jason Bunting (6 anni fa) non funzionerà se possibile La funzione non è definita.
function isFunction(possibleFunction) {
return (typeof(possibleFunction) == typeof(Function));
}
Questo genererà un errore ReferenceError: possibleFunction is not defined
mentre il motore tenta di risolvere il simbolo possibile Funzione (come menzionato nei commenti alla risposta di Jason)
Per evitare questo comportamento, è possibile solo passare il nome della funzione che si desidera verificare se esiste. Così
var possibleFunction = possibleFunction || {};
if (!isFunction(possibleFunction)) return false;
Questo imposta una variabile in modo che sia la funzione che si desidera verificare o l'oggetto vuoto se non è definito e quindi evita i problemi sopra menzionati.
Provare:
if (typeof(callback) == 'function')
Potrei farlo
try{
callback();
}catch(e){};
So che c'è una risposta accettata, ma nessuno l'ha suggerito. Non sono sicuro se questo si adatta alla descrizione dell'idiomatico, ma funziona in tutti i casi.
Nei motori JavaScript più recenti è invece possibile utilizzare un finally
.
if ('function' === typeof callback) ...
function something_cool(text, callback){
alert(text);
if(typeof(callback)=='function'){
callback();
};
}
Prova questo:
callback instanceof Function
Provare:
if (!(typeof(callback)=='undefined')) {...}
Se guardi il fonte della libreria @Venkat Sudheer di cui parla Reddy Aedama, underscorejs, puoi vedere questo:
_.isFunction = function(obj) {
return typeof obj == 'function' || false;
};
Questa è solo la mia risposta SUGGERIMENTO, SUGGERIMENTO:>
Se usi http://underscorejs.org , hai: http://underscorejs.org/#isFunction
_.isFunction(callback);
Stavo cercando come verificare se era stata definita una funzione jQuery e non l'ho trovata facilmente.
Forse potrebbe averne bisogno;)
if(typeof jQuery.fn.datepicker !== "undefined")
Per le funzioni globali puoi usare questo invece di eval
suggerito in una delle risposte.
var global = (function (){
return this;
})();
if (typeof(global.f) != "function")
global.f = function f1_shim (){
// commonly used by polyfill libs
};
Puoi usare anche global.f instanceof Function
, ma afaik. il valore di Function
sarà diverso in frame diversi, quindi funzionerà correttamente solo con un'applicazione a frame singolo. Ecco perché di solito usiamo invece typeof
. Si noti che in alcuni ambienti possono esserci anomalie anche con typeof f
, ad es. da MSIE 6-8 alcune delle funzioni, ad esempio alert
, avevano il tipo "oggetto".
Tramite le funzioni locali è possibile utilizzare quello nella risposta accettata. Puoi verificare se la funzione è anche locale o globale.
if (typeof(f) == "function")
if (global.f === f)
console.log("f is a global function");
else
console.log("f is a local function");
Per rispondere alla domanda, il codice di esempio funziona senza errori negli ultimi browser, quindi non sono sicuro di quale sia stato il problema:
function something_cool(text, callback) {
alert(text);
if( callback != null ) callback();
}
Nota: userei callback !== undefined
invece di callback != null
, ma fanno quasi lo stesso.
La maggior parte se non tutte le risposte precedenti hanno effetti collaterali per invocare la funzione
qui le migliori pratiche
hai una funzione
function myFunction() {
var x=1;
}
//direct way
if( (typeof window.myFunction)=='function')
alert('myFunction is function')
else
alert('myFunction is not defined');
//byString
var strFunctionName='myFunction'
if( (typeof window[strFunctionName])=='function')
alert(s+' is function');
else
alert(s+' is not defined');
Se callback()
che stai chiamando non solo per una volta in una funzione, puoi inizializzare l'argomento per il riutilizzo:
callback = (typeof callback === "function") ? callback : function(){};
Per esempio:
function something_cool(text, callback) {
// Initialize arguments
callback = (typeof callback === "function") ? callback : function(){};
alert(text);
if (text==='waitAnotherAJAX') {
anotherAJAX(callback);
} else {
callback();
}
}
Il limite è che eseguirà sempre l'argomento callback anche se non è definito.