Reputation: 109
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
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