Come sapere se una funzione JavaScript è definita
-
01-07-2019 - |
Domanda
Come si fa a sapere se una funzione in JavaScript è definita?
Voglio fare qualcosa del genere
function something_cool(text, callback) {
alert(text);
if( callback != null ) callback();
}
Ma mi dà un
la richiamata non è una funzione
errore quando la richiamata non è definita.
Soluzione
typeof callback === "function"
Altri suggerimenti
Tutte le risposte attuali utilizzano una stringa letterale, che preferisco non avere nel mio codice, se possibile - questo non lo fa (e fornisce un prezioso significato semantico, per l'avvio):
function isFunction(possibleFunction) {
return typeof(possibleFunction) === typeof(Function);
}
Personalmente, cerco di ridurre il numero di stringhe in giro nel mio codice...
Inoltre, mentre ne sono consapevole typeof
è un operatore e non una funzione, non c'è alcun danno nell'usare la sintassi che lo fa apparire come quest'ultima.
if (callback && typeof(callback) == "function")
Tieni presente che il callback (di per sé) vale false
se è undefined
, null
, 0
, O false
.Rispetto a null
è eccessivamente specifico.
Questi metodi per sapere 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 in 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à a ReferenceError: possibleFunction is not defined
errore mentre il motore tenta di risolvere il simbolo possibileFunzione (come menzionato nei commenti alla risposta di Jason)
Per evitare questo comportamento puoi solo passare il nome della funzione che vuoi verificare se esiste.COSÌ
var possibleFunction = possibleFunction || {};
if (!isFunction(possibleFunction)) return false;
Ciò imposta una variabile come funzione che desideri controllare o come oggetto vuoto se non è definito, evitando così i problemi menzionati sopra.
Tentativo:
if (typeof(callback) == 'function')
Potrei farlo
try{
callback();
}catch(e){};
So che esiste una risposta accettata, ma nessuno lo ha suggerito.Non sono proprio sicuro che questo si adatti alla descrizione di idiomatico, ma funziona per tutti i casi.
Nei motori JavaScript più recenti a finally
può essere utilizzato al suo posto.
if ('function' === typeof callback) ...
typeof(callback) == "function"
function something_cool(text, callback){
alert(text);
if(typeof(callback)=='function'){
callback();
};
}
Prova questo:
callback instanceof Function
Se guardi il fonte della biblioteca menzionata da @Venkat Sudheer Reddy Aedama, underscorejs, puoi vedere questo:
_.isFunction = function(obj) {
return typeof obj == 'function' || false;
};
Questa è solo la mia risposta SUGGERIMENTO, SUGGERIMENTO :>
Tentativo:
if (!(typeof(callback)=='undefined')) {...}
Se usi http://underscorejs.org, hai:http://underscorejs.org/#isFunction
_.isFunction(callback);
Stavo cercando come verificare se era definita una funzione jQuery e non l'ho trovata facilmente.
Forse potrebbe averne bisogno ;)
if(typeof jQuery.fn.datepicker !== "undefined")
Se la callback()
stai chiamando non solo per una volta in una funzione, potresti 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();
}
}
La limitazione è che eseguirà sempre l'argomento callback sebbene non sia definito.
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 global.f instanceof Function
anche, ma afaik.il valore del Function
sarà diverso nei diversi frame, quindi funzionerà correttamente solo con un'applicazione a frame singolo.Ecco perché di solito usiamo typeof
Invece.Si noti che in alcuni ambienti possono verificarsi anomalie typeof f
anche, ad es.da MSIE 6-8 alcune delle funzioni per esempio alert
aveva il tipo "oggetto".
Dalle funzioni locali puoi utilizzare quello nella risposta accettata.Puoi verificare anche se la funzione è 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 nei browser più recenti, quindi non sono sicuro di quale fosse il problema:
function something_cool(text, callback) {
alert(text);
if( callback != null ) callback();
}
Nota:io userei callback !== undefined
invece di callback != null
, ma fanno quasi la stessa cosa.
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');
Soluzione su una riga:
function something_cool(text, callback){
callback && callback();
}