361

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.

0

24 Answers 24

564
typeof callback === "function"
Sign up to request clarification or add additional context in comments.

5 Comments

This isn't really a magic string, since the set of typeof values is precisely defined in the ECMA spec. Although the syntax for this is a little goofy to begin with, it's perfectly reasonable idiomatic Javascript.
@quixoto - understood, I guess what I mean is that you still need to have a string regardless - I would rather not have any more literal strings littering my code than absolutely needed; therefore, this isn't my ideal for testing if something is a function.
And yes, "magic" was a sloppy, poor word choice - I meant "literal string" not "magic string." My bad. :)
Make sure to remove the parenthesis on your function and only use the function name in the if-condition or the function will be invoked instead of giving you true or false.
251

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.

10 Comments

How am I supposed to use this function? I've tried isFunction(not_defined)) where not_defined is name of function that is not defined and FireBug returned not_defined is not defined which is correct but your function should return false and not generate error...
@Wookie88: Technically speaking, the function illustrated in my answer doesn't return an error so much as an error occurs because the JavaScript interpreter is trying to resolve the symbol not_defined in order to pass its value to isFunction() and fails to resolve it. Nothing can be done to the definition of isFunction() to solve this problem.
@ZacharyYates The way to work around the ReferenceError would mean to avoid working with a reference to the maybe-not-defined-function. You could do the typecheck inside the function call and pass the result to the function. jsfiddle.net/qNaxJ Maybe not so nice, but at least, no strings used ;)
Or avoid a function isFunction and do just (typeof no_function == typeof Function).
@JasonBunting If you're going to be that picky, you really should be using typeof(Function()) because Function is a function; but so are Array, Object, and other built-in prototypes (for lack of a better term). If you were checking for an array you wouldn't use typeof(array) === typeof(Array) for example; you'd use typeof(array) === typeof(Array()) because you actually need to evaluate the function if you're being careful and consistent.
|
20
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.

3 Comments

Also note that if callback itself evaluates to a "false-y" value, then its typeof can never be "function".
@Joe, but due to short-circuiting, that test will not be performed if callback evaluates to false.
this solution isn't working, because the first condition will fire an exception immediately. this may work, for a property of an object: if (obj.callback){...}
14

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.

2 Comments

exactly solution i m looking for
And therefore apply or ignore callback using: return callback?.(text)||text;
10

Those methods to tell if a function is implemented also fail if variable is not defined so we are using something more powerful that supports receiving an string:

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

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

3 Comments

I think is a good answer, you are right, all the methods above fails is the function is not defined.
It's trivial to avoid undefined references - simply refer to typeof window.doesthisexist instead of doesthisexist. However, using eval (which: is evil) as shown will only work with named functions - this wouldn't work with the use case in the question.
Be aware that this works only with global scope, while the accepted answer is working with local scope functions as well.
8

Try:

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

1 Comment

HI, do not use "loose" comparison (==) always use '===' to compare even the type of the variable.
8

I might do

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

I know there's an accepted answer, but no one suggested this. I'm not really sure if this fits the description of idiomatic, but it works for all cases.

In newer JavaScript engines a finally can be used instead.

4 Comments

This is a neat shortcut! Though it won't work for solely testing if a function exists or is defined (without also executing it).
That's true. I assumed a situation where the callback is optional at that execution point. I usually use typeof callback anyway.
That makes sense; I was focusing on the question title more than its content. Sometimes I like the simplicity of using try-catch over tons of tests for something. Do you think there's a technical disadvantage to using it, in this case versus something like typeof? Or is it mainly a matter of doing things in a more proper/expected way?
If you want to test for multiple types then exceptions are not so good. For instance the project I'm working on right now uses a lot of type checking on one variable to see if it's a function, string, or whatever. In this project I really need the types. For this I use an array of types, and check accepted_types.indexOf(typeof value) !== -1 to see if it's in a range of types. In this situation exceptions would be prohibitive in my opinion.
6

New to JavaScript I am not sure if the behaviour has changed but the solution given by Jason Bunting (6 years ago) won't work if possibleFunction is not defined.

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

This will throw a ReferenceError: possibleFunction is not defined error as the engine tries to resolve the symbol possibleFunction (as mentioned in the comments to Jason's answer)

To avoid this behaviour you can only pass the name of the function you want to check if it exists. So

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

This sets a variable to be either the function you want to check or the empty object if it is not defined and so avoids the issues mentioned above.

1 Comment

To be completely clear: my code doesn't throw the error, that's just the JavaScript parser doing that. The same would happen if you tried to use any undefined identifier in such a way.
5
typeof(callback) == "function"

Comments

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

Comments

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

3 Comments

A bit pedantic, and still uses a string literal. How about if(typeof Function === typeof callback)...? :)
@JasonBunting Curious, Whats wrong with using string literal?
@Bsienn - as I said, it's pedantic of me, but here's the thing. Let's say you use the code with the string literal, and the call to typeof returns something different later (maybe "Function" instead of "function"), because of a new/different implementation of JavaScript - it feels like it would be less likely that a new/different implementation would break the typeof Function === typeof callback check because it should be the same at a semantic level.
4

Try:

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

Comments

2

Try this:

callback instanceof Function

6 Comments

Doesn't work. It will still give you the error. You should try it yourself before you post it as an answer.
@vbullinger I just tested again in Chrome, Firefox and Safari — works everywhere. With which engine did you experience trouble?
Firefox. Did you test the case when callback wasn't defined?
That's because you're directly referencing an undefined variable, that never works: pastebin.com/UQz2AmzH
It does work when used on a function parameter, which is what the author asked for — I suppose ECMAScript distinguishes the cases of a non-existent variable and an existing variable with a value of undefined. It would be interesting to know more about this.
|
2

If you use http://underscorejs.org, you have: http://underscorejs.org/#isFunction

_.isFunction(callback);

Comments

2

If you look at the source of the library @Venkat Sudheer Reddy Aedama mentioned, underscorejs, you can see this:

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

This is just my HINT, HINT answer :>

Comments

1

I was looking for how to check if a jQuery function was defined and I didn't find it easily.

Perhaps might need it ;)

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

1 Comment

same as type0f($.datepicker) !== undefiled otherwise will be object
1

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.

Comments

1

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');

1 Comment

not sure why you have 'window' here . There could be scope differences : just do typeof(myFunction) === 'function'
1

This is what worked for me it always better to check whether 'undefined' at first

if(typeof ShowDialogOpen != 'undefined' && typeof ShowDialogOpen==='function'){
  console.log('function available');
}
else{
  console.log('function NOT available');
}

Comments

0

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.

Comments

0

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

Comments

0

This worked for me

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

Comments

-1

I would rather suggest following function:

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

1 Comment

The question asked for a way to determine if a variable is a function, not a string that is the name of a function.
-2

One-line solution:

function something_cool(text, callback){
    callback && callback();
}

2 Comments

His example shows just that, that he wants the function to be called if it's defined, and if it's not, nothing happens. jsfiddle.net/nh1cxxg6 Functions which return falsey / false values still get called. Of course, this doesn't work for when you want values to be returned.
Ah, I misread his question. However, this would cause an exception if callback is not a function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.