How to tell if a JavaScript function is defined

Viewed 206133

How do you tell if a function in JavaScript is defined?

I want to do something like this

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

But it gets me a

callback is not a function

error when callback is not defined.

23 Answers

All of the current answers use a literal string, which I prefer to not have in my code if possible - this does not (and provides valuable semantic meaning, to boot):

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

Personally, I try to reduce the number of strings hanging around in my code...


Also, while I am aware that typeof is an operator and not a function, there is little harm in using syntax that makes it appear as the latter.

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

Note that callback (by itself) evaluates to false if it is undefined, null, 0, or false. Comparing to null is overly specific.

Try:

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

Try:

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

Using optional chaining with function calls you could do the following:

function something_cool(text, callback) {
    alert(text);
    callback?.();
}

If callback is a function, it will be executed.

If callback is null or undefined, no error is thrown and nothing happens.

However, if callback is something else e.g. a string or number, a TypeError will still be thrown.

If the callback() you are calling not just for one time in a function, you could initialize the argument for reuse:

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

For example:

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

    alert(text);

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

The limitation is that it will always execute the callback argument although it's undefined.

For global functions you can use this one instead of eval suggested in one of the answers.

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

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

You can use global.f instanceof Function as well, but afaik. the value of the Function will be different in different frames, so it will work only with a single frame application properly. That's why we usually use typeof instead. Note that in some environments there can be anomalies with typeof f too, e.g. by MSIE 6-8 some of the functions for example alert had "object" type.

By local functions you can use the one in the accepted answer. You can test whether the function is local or global too.

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

To answer the question, the example code is working for me without error in latest browers, so I am not sure what was the problem with it:

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

Note: I would use callback !== undefined instead of callback != null, but they do almost the same.

Most if not all previous answers have side effects to invoke the function

here best practice

you have function

function myFunction() {
        var x=1;
    }
direct way to test for it

//direct way
        if( (typeof window.myFunction)=='function')
            alert('myFunction is function')
        else
            alert('myFunction is not defined');
using a string so you can have only one place to define function name

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

If you wish to redefine functions, it is best to use function variables, which are defined in their order of occurrence, since functions are defined globally, no matter where they occur.

Example of creating a new function that calls a previous function of the same name:

A=function() {...} // first definition
...
if (typeof A==='function')
   oldA=A;
A=function() {...oldA()...} // new definition

This worked for me

if( cb && typeof( eval( cb ) ) === "function" ){
    eval( cb + "()" );
}

I would rather suggest following function:

function isFunction(name) {
    return eval(`typeof ${name} === typeof Function`);
}
Related