How to check if function exists in JavaScript?

Solution 1:

Try something like this:

if (typeof me.onChange !== "undefined") { 
    // safe to use the function
}

or better yet (as per UpTheCreek upvoted comment)

if (typeof me.onChange === "function") { 
    // safe to use the function
}

Solution 2:

I had this problem.

if (obj && typeof obj === 'function') { ... }

kept throwing a reference error if obj happened to be undefined.

In the end I did the following:

if (typeof obj !== 'undefined' && typeof obj === 'function') { ... }

A colleague pointed out to me that checking if it's !== 'undefined' and then === 'function' is redundant of course.

Simpler:

if (typeof obj === 'function') { ... }

Much cleaner and works great.

Solution 3:

Modern JavaScript to the rescue!

In 2021, this is solved* in JavaScript (and TypeScript) with the new Optional Chaining syntax.

me.onChange?.(str)

If onChange exists, it gets called.

If onChange does not exist, nothing happens: the expression returns undefined.

So for let value = me.onChange?.(str), value will be undefined if onChange does not exist.

Note, if onChange exists but is not a function, it throws a TypeError just the same as if you call any non-function as a function. Optional Chaining doesn't do any magic to make this go away.

* Optional Chaining is a stage 4 TC39 proposal, meaning it's not officially in the ECMAScript spec yet, but is essentially guaranteed to be included in the next version. You can use it today via Babel or TypeScript with confidence the syntax won't change.

Solution 4:

If you're using eval to convert a string to function, and you want to check if this eval'd method exists, you'll want to use typeof and your function string inside an eval:

var functionString = "nonexsitantFunction"
eval("typeof " + functionString) // returns "undefined" or "function"

Don't reverse this and try a typeof on eval. If you do a ReferenceError will be thrown:

var functionString = "nonexsitantFunction"
typeof(eval(functionString)) // returns ReferenceError: [function] is not defined

Solution 5:

How about:

if('functionName' in Obj){
    //code
}

e.g.

var color1 = new String("green");
"length" in color1 // returns true
"indexOf" in color1 // returns true
"blablabla" in color1 // returns false

or as for your case:

if('onChange' in me){
    //code
}

See MDN docs.