Pergunta

Como você dizer se uma função em JavaScript é definida?

Eu quero fazer algo parecido com isto

function something_cool(text, callback) {
    alert(text);
    if( callback != null ) callback();
}

Mas isso me deixa um

callback não é uma função

erro ao retorno não está definido.

Foi útil?

Solução

typeof callback === "function"

Outras dicas

Todas as respostas atuais utilizar uma string literal, que eu prefiro não ter no meu código, se possível - isso não faz (e fornece valioso significado semântico, para boot):

function isFunction(possibleFunction) {
  return typeof(possibleFunction) === typeof(Function);
}

Pessoalmente, eu tentar reduzir o número de cordas penduradas em torno no meu código ...


Além disso, enquanto eu estou ciente de que typeof é uma operadora e não uma função, há pouco mal em usar sintaxe que faz parecer que o último.

if (callback && typeof(callback) == "function")

Note que retorno de chamada (por si só) avalia para false se for undefined, null, 0, ou false. Comparando com null é excessivamente específico.

Esses métodos para dizer se uma função é implementada também falhar se variável não é definida por isso estamos usando algo mais poderoso que suporta receber uma string:

function isFunctionDefined(functionName) {
    if(eval("typeof(" + functionName + ") == typeof(Function)")) {
        return true;
    }
}

if (isFunctionDefined('myFunction')) {
    myFunction(foo);
}

Novo para JavaScript Não estou certo se o comportamento mudou, mas a solução dada por Jason Bunting (6 anos) não funcionará se possibleFunction não está definido.

function isFunction(possibleFunction) {
  return (typeof(possibleFunction) == typeof(Function));
}

Isto irá lançar um erro ReferenceError: possibleFunction is not defined como as tentativas de mecanismo para resolver o símbolo possibleFunction (como mencionado nos comentários a resposta de Jason)

Para evitar esse comportamento só pode passar o nome da função que pretende verificar se ele existir. Então

var possibleFunction = possibleFunction || {};
if (!isFunction(possibleFunction)) return false;

Isso define uma variável para ser a função que deseja verificar ou o objeto vazio se não for definido e assim evita os problemas acima mencionados.

Tente:

if (typeof(callback) == 'function')

Eu poderia fazer

try{
    callback();
}catch(e){};

Eu sei que há uma resposta aceita, mas ninguém sugeriu isso. Eu realmente não estou certo se isso se encaixa na descrição de idiomática, mas funciona para todos os casos.

Nos motores mais recentes JavaScript um finally pode ser utilizado.

if ('function' === typeof callback) ...
typeof(callback) == "function"
function something_cool(text, callback){
    alert(text);
    if(typeof(callback)=='function'){ 
        callback(); 
    };
}

Tente isto:

callback instanceof Function

Se você olhar para o fonte da biblioteca @Venkat Sudheer Reddy Aedama mencionado, underscorejs, você pode ver o seguinte:

_.isFunction = function(obj) {
  return typeof obj == 'function' || false;
};

Esta é apenas a minha dica, resposta DICA:>

Tente:

if (!(typeof(callback)=='undefined')) {...}

Se você usar http://underscorejs.org , você tem: http://underscorejs.org/#isFunction

_.isFunction(callback);

eu estava procurando como verificar se uma função jQuery foi definido e eu não encontrá-lo facilmente.

Talvez pode precisar dele;)

if(typeof jQuery.fn.datepicker !== "undefined")

Se o callback() você está chamando não só por um tempo em uma função, você pode inicializar o argumento para reutilização:

callback = (typeof callback === "function") ? callback : function(){};

Por exemplo:

function something_cool(text, callback) {
    // Initialize arguments
    callback = (typeof callback === "function") ? callback : function(){};

    alert(text);

    if (text==='waitAnotherAJAX') {
        anotherAJAX(callback);
    } else {
        callback();
    }
}

A limitação é que ele sempre irá executar o argumento de retorno de chamada, embora ela é indefinida.

Para funções globais que você pode usar este em vez de eval sugerido em uma das respostas.

var global = (function (){
    return this;
})();

if (typeof(global.f) != "function")
    global.f = function f1_shim (){
        // commonly used by polyfill libs
    };

Você pode usar global.f instanceof Function bem, mas afaik. o valor da Function será diferente em diferentes quadros, por isso vai trabalhar apenas com uma única aplicação quadro corretamente. É por isso que geralmente usamos typeof vez. Note-se que em alguns ambientes pode haver anomalias com typeof f também, por exemplo, por MSIE 6-8 algumas das funções por exemplo alert tinha tipo "objeto".

Por funções locais você pode usar o um na resposta aceita. Você pode testar se a função é local ou global também.

if (typeof(f) == "function")
    if (global.f === f)
        console.log("f is a global function");
    else
        console.log("f is a local function");

Para responder à pergunta, o código de exemplo está funcionando para mim sem erro em mais browers, então eu não tenho certeza qual era o problema com ele:

function something_cool(text, callback) {
    alert(text);
    if( callback != null ) callback();
}

Nota: eu usaria callback !== undefined vez de callback != null, mas eles fazem quase o mesmo

.

A maioria, se não todas as respostas anteriores têm efeitos colaterais para invocar a função

aqui melhores práticas

Você tem função

function myFunction() {
        var x=1;
    }
maneira direta de teste para ele

//direct way
        if( (typeof window.myFunction)=='function')
            alert('myFunction is function')
        else
            alert('myFunction is not defined');
usando uma corda para que você pode ter apenas um lugar para definir o nome da função

//byString
        var strFunctionName='myFunction'
        if( (typeof window[strFunctionName])=='function')
            alert(s+' is function');
        else
            alert(s+' is not defined');

solução de uma linha:

function something_cool(text, callback){
    callback && callback();
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top