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.

È stato utile?

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;
    }
modo diretto per testarlo

//direct way
        if( (typeof window.myFunction)=='function')
            alert('myFunction is function')
        else
            alert('myFunction is not defined');
utilizzando una stringa in modo da poter avere un solo posto per definire il nome della funzione

//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();
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top