How to Check if a Function is Defined in JavaScript

avatar
Borislav Hadzhiev

Last updated: Mar 3, 2024
4 min

banner

# Check if a Function is Defined in JavaScript

Use the typeof operator to check if a function is defined.

The typeof operator returns a string that indicates the type of a value. If the function is not defined, the typeof operator returns "undefined" and doesn't throw an error.

index.js
function greet() { return 'hello world'; } if (typeof greet === 'function') { // ๐Ÿ‘‡๏ธ this runs console.log('โœ… function is defined'); console.log(greet()); // ๐Ÿ‘‰๏ธ hello world } else { console.log('โ›”๏ธ function is NOT defined'); }

check if function is defined

The code for this article is available on GitHub

We used the typeof operator to check if a function is defined.

The operator returns a string that indicates the type of a value. Here are some examples:

index.js
console.log(typeof (() => {})); // ๐Ÿ‘‰๏ธ "function" console.log(typeof function () {}); // ๐Ÿ‘‰๏ธ "function" console.log(typeof null); // ๐Ÿ‘‰๏ธ "object" console.log(typeof []); // ๐Ÿ‘‰๏ธ "object" console.log(typeof {}); // ๐Ÿ‘‰๏ธ "object" console.log(typeof ''); // ๐Ÿ‘‰๏ธ "string" console.log(typeof 0); // ๐Ÿ‘‰๏ธ "number"

using typeof operator

The typeof operator doesn't throw an error when used with a variable that is not declared, instead, it returns the string "undefined".

index
console.log(typeof doesNotExist); // ๐Ÿ‘‰๏ธ "undefined"

However, if you use the typeof operator before declaring a variable with the let or const keywords, you would get an error.

index.js
// โ›”๏ธ ReferenceError: Cannot access 'myFunction' before initialization if (typeof myFunction === 'function') { console.log('โœ… function is defined'); } else { console.log('โ›”๏ธ function is NOT defined'); } const myFunction = () => {};
The code for this article is available on GitHub

We used the typeof operator before initializing a function using the const keyword.

This causes an error because we are trying to access a variable that exists in the program but is not yet declared.

We would get the same result if we declared the function using the let keyword.

However, if we use the var keyword, we won't get an error because of how hoisting works in JavaScript.

index.js
if (typeof myFunction === 'function') { console.log('โœ… function is defined'); } else { // ๐Ÿ‘‡๏ธ This runs console.log('โ›”๏ธ function is NOT defined'); } var myFunction = () => {};

We declared the function using the var keyword, so we didn't get an error when using the typeof operator, however, the else block ran.

This is what happens under the hood when using the var keyword.

index.js
var myFunction; if (typeof myFunction === 'function') { console.log('โœ… function is defined'); } else { // ๐Ÿ‘‡๏ธ This runs console.log('โ›”๏ธ function is NOT defined'); } myFunction = () => {};
The code for this article is available on GitHub

The declaration of the variable gets hoisted to the top, however, the assignment of the value remains where it is.

Named functions get hoisted to the top, so you can call a named function even before the line on which it is declared.

index.js
if (typeof greet === 'function') { // ๐Ÿ‘‡๏ธ this runs console.log('โœ… function is defined'); console.log(greet()); // ๐Ÿ‘‰๏ธ hello world } else { console.log('โ›”๏ธ function is NOT defined'); } function greet() { return 'hello world'; }

You can imagine that the declaration of the greet() function was moved to line 1.

When the if statement runs, the function is available in the scope and can be called.

Note that only named functions (ones that use the function keyword) get hoisted to the top of the file.

# Check if a Function is Defined using a try/catch block

This is a three-step process:

  1. Call the function in a try/catch statement.
  2. If the function is defined, the try block will run successfully.
  3. Otherwise, the catch block will run.
index.js
try { const result = greet(); console.log(result); // ๐Ÿ‘‰๏ธ hello world } catch (err) { console.log('The function is not defined'); } function greet() { return 'hello world'; }

check if function is defined using try catch block

The code for this article is available on GitHub

We called the function in a try/catch block.

The function is defined and available in the scope, so the try block completed.

If the function is not defined, the catch block runs.

index.js
try { const result = greet(); console.log(result); } catch (err) { // ๐Ÿ‘‡๏ธ this runs console.log('The function is not defined'); }

We tried to call a function that doesn't exist in the scope, so the error got passed to the catch block.

The catch block handles the error, so your program won't crash due to an unhandled error.

# Check if a Variable is of type Function using instanceof

You can also use the instanceof operator to check if a variable is a function.

The instanceof operator will return true if the variable is of type function and false otherwise.

index.js
function sum(a, b) { return a + b; } if (sum instanceof Function) { // ๐Ÿ‘‡๏ธ this runs console.log('โœ… The variable is of type function'); } else { console.log('โ›”๏ธ The variable is NOT of type function'); }

check if variable is of type function using instanceof

The code for this article is available on GitHub

The syntax for the instanceof operator is object instanceof constructor.

The operator returns true if the prototype property of the constructor appears anywhere in the prototype chain of the object.

One thing to note about the instanceof operator is that it won't work as expected if you're checking a function that is from another document, e.g. an iframe.

Each document will have its own Function object, so the instanceof check should not be used in this scenario.

The typeof operator would work as expected even if the function comes from a different document (e.g. an iframe).

# Check if a Variable is of type Function using string comparison

You can also convert a value to a string to check if it is a function.

index.js
function isTypeFunction(f) { const functionTypes = [ '[object Function]', '[object AsyncFunction]', ]; return functionTypes.includes( Object.prototype.toString.call(f), ); } // โœ… synchronous function function subtract(a, b) { return a - b; } // โœ… asynchronous function async function sum(a, b) { return a + b; } console.log(isTypeFunction(sum)); // ๐Ÿ‘‰๏ธ true console.log(isTypeFunction(subtract)); // ๐Ÿ‘‰๏ธ true console.log(isTypeFunction('abc')); // ๐Ÿ‘‰๏ธ false

check if variable is of type function using string comparison

The code for this article is available on GitHub

We used the toString() method to convert the passed-in value to a string and compared the output to the result of calling the method with a function.

index.js
// โœ… for sync functions function subtract(a, b) { return a - b; } // ๐Ÿ‘‡๏ธ "[object Function]" console.log(Object.prototype.toString.call(subtract)); // -------------------------------------------------- // โœ… for async functions async function sum(a, b) { return a + b; } // ๐Ÿ‘‡๏ธ "[object AsyncFunction]" console.log(Object.prototype.toString.call(sum));

Converting a synchronous function to a string returns "[object Function]", whereas converting an async function to a string returns "[object AsyncFunction]".

This code sample is for demonstration purposes only as there is no good reason to use this approach.

Using the typeof operator should be your preferred approach as it is the most performant, readable and works between different contexts (e.g. in iframes).

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev