Aishwarya Singhal
Aishwarya Singhal

Reputation: 109

What is the best way to check if variable is a function?

I have gone through multiple approaches to check if a variable is a function but I can't figure out the advantages and disadvantages, which one to use and why.

Are there any edge cases where my comparison can fail in case of typeof?

1) function isFunction(functionToCheck) { return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]'; }

2) typeof functionToCheck === 'function'

3) functionToCheck.constructor === Function

Upvotes: 3

Views: 2732

Answers (1)

yqlim
yqlim

Reputation: 7080

In a perfect world, all of them should return the same value.

const functionToCheck = () => {};


console.log(isFunction(functionToCheck));
console.log(typeof functionToCheck === 'function');
console.log(functionToCheck.constructor === Function);
console.log(functionToCheck instanceof Function);


function isFunction(functionToCheck){
  return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]';
}

In real world, their difference can be significant.

const functionToCheck = () => {};

// Altering `.toString()` function by some third-party code
Object.prototype.toString = function(){
  return '[ABCDEFG]';
}

// Mistake of programmer
functionToCheck.constructor = HTMLElement;

// Having a global scope variable named `Function` by some third-party code
window.Function = class ABC {};


console.log(isFunction(functionToCheck));
console.log(typeof functionToCheck === 'function');
console.log(functionToCheck.constructor === Function);
console.log(functionToCheck instanceof Function);


function isFunction(functionToCheck){
  return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]';
}

As you can see, I can freely alter the functions and constructor which in turn alter the results that you expect.

The safest way is to always use typeof to check a function as its result cannot be altered in any way.

Upvotes: 4

Related Questions