1286

Suppose I have any variable, which is defined as follows:

var a = function() {/* Statements */};

I want a function which checks if the type of the variable is function-like. i.e. :

function foo(v) {if (v is function type?) {/* do something */}};
foo(a);

How can I check if the variable a is of type Function in the way defined above?

0

22 Answers 22

2331
if (typeof v === 'function') {
    // do something
}
Sign up to request clarification or add additional context in comments.

4 Comments

What is the difference with if (v instanceOf Function)?
@mquandalle No big difference, except instanceof won't work if you're checking a function that came from another document (an iframe, maybe). Performance varies.
unlike the accepted answer this works for async functions too. For an asyncfunctionToCheck, getType.toString.call(functionToCheck)==='[object AsyncFunction]' where as typeof asyncfunctionToCheck === 'function'
449

Sure underscore's way is more efficient, but the best way to check, when efficiency isn't an issue, is written on underscore's page linked by @Paul Rosania.

Inspired by underscore, the final isFunction function is as follows:

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

Note: This solution doesn't work for async functions, generators or proxied functions. Please see other answers for more up to date solutions.

5 Comments

It looks like there's a huge speed difference depending on your browser. In Chrome typeof(obj) === 'function' appears to be the fastest by far; however, in Firefox obj instanceof Function is the clear winner.
Regarding the part: typeof should only be used for checking if variables or properties are undefined. At javascript.info/tutorial/type-detection in the A good use of typeof section and the following one the author states, that the case is exactly the opposite
can someone please explain me the meaning of this string? what does {}.toString does? And {}.toString.call(functionToCheck)?
This has to be the worst answer I've ever seen as accepted with this many viewers (555k!!!). This is convoluted and unreadable. You should edit your answer so that people don't use this solution in their own code.
Update 9 years later: this will not work on recent versions of IOS when the function is behind a Proxy.
222

There are several ways so I will summarize them all

  1. Best way is:
    function foo(v) {if (v instanceof Function) {/* do something */} };
    

    Most performant (no string comparison) and elegant solution - the instanceof operator has been supported in browsers for a very long time, so don't worry - it will work in IE 6.

  2. Next best way is:
    function foo(v) {if (typeof v === "function") {/* do something */} };
    

    disadvantage of typeof is that it is susceptible to silent failure, bad, so if you have a typo (e.g. "finction") - in this case the if will just return false and you won't know you have an error until later in your code

  3. The next best way is:
    function isFunction(functionToCheck) {
        var getType = {};
        return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
    }
    

    This has no advantage over solution #1 or #2 but is a lot less readable. An improved version of this is

    function isFunction(x) {
        return Object.prototype.toString.call(x) == '[object Function]';
    }
    

    but still lot less semantic than solution #1

2 Comments

The first solution fails in case of a function passed to a different frame context. For example, from an iframe top.Function !== Function. To be sure, use the second one (any misspelling of "function" would be corrected during debug, hopefully).
host objects don't have prototypes in IE6 and yet can be functions. Hence typeof window.alert=="function" || window.alert instanceof Function returns false. You can still test for such functions in IE6 by first checking if it's a host object and then by testing if its toString method is either "undefined" or "unknown". In the latter case that means it's a constructor function such as XMLHttpRequest.
145

Underscore.js uses a more elaborate but highly performant test:

_.isFunction = function(obj) {
  return !!(obj && obj.constructor && obj.call && obj.apply);
};

See: https://jsben.ch/B6h73

EDIT: updated tests suggest that typeof might be faster, see https://jsben.ch/B6h73

4 Comments

I sure do like underscore, simple but powerful. That said, its probably worth noting that this implementation could be spoofed by an object with those attributes.
This answer is a bit misleading now, as Underscore.js is now on revision 12 not the above-referenced revision 4, of its test of alternative isFunction() implementations. It currently uses something very close to what dandean suggested.
This test is wrong; consider: given var f = function(x) { return x + 1; }; Object.setPrototypeOf(f, Object.prototype);, f is still a function (f(2) returns 3), but f.call and f. apply are both undefined.
Underscore.js now uses typeof obj == 'function' || false. (Source)
92

jQuery (deprecated since version 3.3) Reference

$.isFunction(functionName);

AngularJS Reference

angular.isFunction(value);

Lodash Reference

_.isFunction(value);

Underscore Reference

_.isFunction(object); 

Node.js deprecated since v4.0.0 Reference

var util = require('util');
util.isFunction(object);

Comments

62

@grandecomplex: There's a fair amount of verbosity to your solution. It would be much clearer if written like this:

function isFunction(x) {
  return Object.prototype.toString.call(x) == '[object Function]';
}

3 Comments

Object.prototype.toString.call is useful for other javascript types your interested in. You can even check against null or undefined which makes it very powerful.
This doesn't work for async functions nor generator functions
@lwdthe1 Excellent point: var f = async () => 5; Object.prototype.toString.call(f) gives '[object AsyncFunction]' Not insane or out of left field, but good to keep in mind.
59
+50

Something with more browser support and also include async functions could be:

const isFunction = value => value ? (Object.prototype.toString.call(value) === "[object Function]" || "function" === typeof value || value instanceof Function) : false;

and then test it like:

isFunction(isFunction); //true
isFunction(function(){}); //true
isFunction(()=> {}); //true
isFunction(()=> {return 1}); //true
isFunction(async function asyncFunction(){}); //true
isFunction(Array); //true
isFunction(Date); //true
isFunction(Object); //true
isFunction(Number); //true
isFunction(String); //true
isFunction(Symbol); //true
isFunction({}); //false
isFunction([]); //false
isFunction("function"); //false
isFunction(true); //false
isFunction(1); //false
isFunction("Alireza Dezfoolian"); //false

2 Comments

isFunction(null) or isFunction(undefined) returns null instead of true or false.
Also isFunction('[object Function]') gives a false positive
51

const foo = function() {};
if (typeof foo === 'function') {
  console.log('is function')
}

1 Comment

...and (() => (typeof obj === 'function') && doSomething()) is still fastest option.
43

Try the instanceof operator: it seems that all functions inherit from the Function class:

// Test data
var f1 = function () { alert("test"); }
var o1 = { Name: "Object_1" };
F_est = function () { };
var o2 = new F_est();

// Results
alert(f1 instanceof Function); // true
alert(o1 instanceof Function); // false
alert(o2 instanceof Function); // false

1 Comment

As is pointed out elsewhere, this can fail if the function comes from another document (e.g. iframe), as each will have its own separate Function.
13

An other simply way:

var fn = function () {}
if (fn.constructor === Function) {
  // true
} else {
  // false
}

2 Comments

if fn will be undefined it will throw an Error
fn && fn.constructor === Function how about this?
12

For those who's interested in functional style, or looks for more expressive approach to utilize in meta programming (such as type checking), it could be interesting to see Ramda library to accomplish such task.

Next code contains only pure and pointfree functions:

const R = require('ramda');

const isPrototypeEquals = R.pipe(Object.getPrototypeOf, R.equals);

const equalsSyncFunction = isPrototypeEquals(() => {});

const isSyncFunction = R.pipe(Object.getPrototypeOf, equalsSyncFunction);

As of ES2017, async functions are available, so we can check against them as well:

const equalsAsyncFunction = isPrototypeEquals(async () => {});

const isAsyncFunction = R.pipe(Object.getPrototypeOf, equalsAsyncFunction);

And then combine them together:

const isFunction = R.either(isSyncFunction, isAsyncFunction);

Of course, function should be protected against null and undefined values, so to make it "safe":

const safeIsFunction = R.unless(R.isNil, isFunction);

And, complete snippet to sum up:

const R = require('ramda');

const isPrototypeEquals = R.pipe(Object.getPrototypeOf, R.equals);

const equalsSyncFunction = isPrototypeEquals(() => {});
const equalsAsyncFunction = isPrototypeEquals(async () => {});

const isSyncFunction = R.pipe(Object.getPrototypeOf, equalsSyncFunction);
const isAsyncFunction = R.pipe(Object.getPrototypeOf, equalsAsyncFunction);

const isFunction = R.either(isSyncFunction, isAsyncFunction);

const safeIsFunction = R.unless(R.isNil, isFunction);

// ---

console.log(safeIsFunction( function () {} ));
console.log(safeIsFunction( () => {} ));
console.log(safeIsFunction( (async () => {}) ));
console.log(safeIsFunction( new class {} ));
console.log(safeIsFunction( {} ));
console.log(safeIsFunction( [] ));
console.log(safeIsFunction( 'a' ));
console.log(safeIsFunction( 1 ));
console.log(safeIsFunction( null ));
console.log(safeIsFunction( undefined ));

However, note the this solution could show less performance than other available options due to extensive usage of higher-order functions.

Comments

7

If you use Lodash you can do it with _.isFunction.

_.isFunction(function(){});
// => true

_.isFunction(/abc/);
// => false

_.isFunction(true);
// => false

_.isFunction(null);
// => false

This method returns true if value is a function, else false.

Comments

7

This is an old question but there are some considerations in 2022:

First, browser compatibility: instanceof is supported by all modern browsers as well as Deno and NodeJS. Also, it's syntactically readable and more friendly than typeof. Finally, it provides a good performance over string comparison but is slower than typeof. Therefore, for me this is the a good option

const fnc = () => {}
const isFunction = f => !!f && f instanceof Function
const isFunctionFaster = f => !!f && 'function' === typeof f

console.log({
  isFunction: isFunction(fnc),
  isFunctionFaster: isFunctionFaster(fnc),
})

Notice

It is important to understand that this is a optimized function for benchmarking. When you bench mark you want to pass all the test like null, undefined and some on possible parameters received. f && ... filter this null like parameters to reduce computation time.

This operator tests the presence of constructor.prototype in the object's prototype chain. This usually (though not always) means object was constructed with constructor. Therefore, this process is slower compared with typeof operator.

typeof v === 'function')

This operator returns a string indicating the type of the operand's value. This is executed very fast.

  • Caveats of instanceof and typeof operators:

Remember that a class declaration, it's also considered as a function by the these operators, as you can see in this snippet:

// Class Declaration
class A {}

// Instances
const obj = {}
const arr = []
const fnc = () => {}
const a = new A()

console.log('typeof')
console.log(`Object[${typeof Object}], obj[${typeof obj}]`)
console.log(`Array[${typeof Array}], arr[${typeof arr}]`)
console.log(`Function[${typeof Function}], fnc[${typeof fnc}]`)
console.log(`A[${typeof A}], a[${typeof a}]`)

console.log('instanceof')
console.log(`Object[${Object instanceof Object}], obj[${obj instanceof Object}]`)
console.log(`Array[${Array instanceof Array}], arr[${arr instanceof Array}]`)
console.log(`Function[${Function instanceof Function}], fnc[${fnc instanceof Function}]`)
console.log(`A[${A instanceof A}], a[${a instanceof A}]`)

Here is a basic sample of the isFunction and isFunctionFaster usage with different instances:

// Functions
const isNil = o => o == null
const isFunction = f => !!f && f instanceof Function
const isFunctionFaster = f => !!f && 'function' === typeof f

class A {}

function basicFnc(){}
async function asyncFnc(){}

const arrowFnc = ()=> {}
const arrowRFnc = ()=> 1

// Not functions
const obj = {}
const arr = []
const str = 'function'
const bol = true
const num = 1
const a = new A()

const list = [
    isFunction,
    isFunctionFaster,
    basicFnc,
    arrowFnc,
    arrowRFnc,
    asyncFnc,
    Array,
    Date,
    Object,
    Number,
    String,
    Symbol,
    A,
    obj,
    arr,
    str,
    bol,
    num,
    a,
    null,
    undefined,
]

for (const arg of list) {
  console.log(`${arg} is a function: ${isFunction(arg)}`)
}

Here is a basic benchmark of these functions:

/**
 * Figure out how long it takes for a method to execute.
 * 
 * @param {Function} method to test 
 * @param {number} iterations number of executions.
 * @param {Array} args to pass in. 
 * @param {T} context the context to call the method in.
 * @return {number} the time it took, in milliseconds to execute.
 */
const bench = (method, list, iterations, context) => {
    let start = 0
    const timer = action => {
        const time = performance.now()
        switch (action) {
            case 'start':
                start = time
                return 0
            case 'stop':
                const elapsed = time - start
                start = 0
                return elapsed
            default:
                return time - start
        }
    };

    const result = []
    timer('start')
    list = [...list]
    for (let i = 0; i < iterations; i++) {
      for (const args of list) {
        result.push(method.apply(context, args))
      }
    }
    const elapsed = timer('stop')
    
    console.log(`Called method [${method.name}]`)
    console.log(`Mean: ${elapsed / iterations}`)
    console.log(`Exec. time: ${elapsed}`)

    return elapsed
}

const fnc = () => {}
const isFunction = (f) => f && f instanceof Function
const isFunctionFaster = (f) => f && 'function' === typeof f


class A {}

function basicFnc(){}
async function asyncFnc(){}

const arrowFnc = ()=> {}
const arrowRFnc = ()=> 1

// Not functions
const obj = {}
const arr = []
const str = 'function'
const bol = true
const num = 1
const a = new A()

const list = [
    [isFunction],
    [basicFnc],
    [arrowFnc],
    [arrowRFnc],
    [asyncFnc],
    [Array],
    [Date],
    [Object],
    [Number],
    [String],
    [Symbol],
    [A],
    [obj],
    [arr],
    [str],
    [bol],
    [num],
    [a],
    [null],
    [undefined],
]

const e1 = bench(isFunction, list, 10000)
const e2 = bench(isFunctionFaster, list, 10000)

const rate = e2/e1
const percent = Math.abs(1 - rate)*100

console.log(`[isFunctionFaster] is ${(percent).toFixed(2)}% ${rate < 1 ? 'faster' : 'slower'} than [isFunction]`)

Conclusion

In general isFunctionFaster is faster than isFunction in 30%.

Comments

5

The below seems to work for me as well (tested from node.js):

var isFunction = function(o) {
     return Function.prototype.isPrototypeOf(o);
};

console.log(isFunction(function(){})); // true
console.log(isFunction({})); // false

Comments

4

I found that when testing native browser functions in IE8, using toString, instanceof, and typeof did not work. Here is a method that works fine in IE8 (as far as I know):

function isFn(f){
    return !!(f && f.call && f.apply);
}
//Returns true in IE7/8
isFn(document.getElementById);

Alternatively, you can check for native functions using:

"getElementById" in document

Though, I have read somewhere that this will not always work in IE7 and below.

Comments

4

I think you can just define a flag on the Function prototype and check if the instance you want to test inherited that

define a flag:

Function.prototype.isFunction = true; 

and then check if it exist

var foo = function(){};
foo.isFunction; // will return true

The downside is that another prototype can define the same flag and then it's worthless, but if you have full control over the included modules it is the easiest way

1 Comment

It will fail with Error if foo is undefined. Not mentioning that you modify native prototype which is totally wrong.
3

you should use typeOf operator in js.

var a=function(){
    alert("fun a");
}
alert(typeof a);// alerts "function"

Comments

3

Since node v0.11 you can use the standard util function :

var util = require('util');
util.isFunction('foo');

1 Comment

util.isFunction is deprecated
2

if you are looking for a simple solution:

 function isFunction(value) {
   return value instanceof Function
}

Comments

1

There are functions whose arguments can be passed either as a value or though a callback. To implement them a nice helper function that utilizes type detection is the following:

const toCallback = (v)=>(v instanceof Function)?v:()=>v

Then let's say you want to implement a function that can receive either a fixed value or a callback that returns the value. See below:

let someFunction=(valueOrFunction)=>{
    let f = toCallback(valueOrFunction); 
    [1,2,3].forEach(v=>console.log(`value passed: ${f()}`))   
}

and now you can execute the above in two ways:

someFunction(5);
//value passed: 5
//value passed: 5
//value passed: 5

someFunction(()=>Math.random());
//value passed: 0.3218832537523002
//value passed: 0.2343617971814611
//value passed: 0.38216627030533656

Comments

1

This is a bit tricky question as you need to define "what is a function?" first. Let's look at node (V8 implementation of JavaScript engine). It is written in C++ but also has parts in JavaScript. Some functions are magically mapped to C++ functions. Those do not have all the properties of standard function. Other functions are simply JavaScript functions with prototype set to null. It means they don't inherit from Object and wouldn't have methods such as toString() and similar. Then finally you have standard instances of Function. And there is also AsyncFunction which is a Function but a bit different. Think what about a promise that returns a function - is it a Function or rather a Promise? Is Promise a Function?

This told let's see how node implements checking if an argument is an AsyncFunction: readable-stream defined AsyncFunction as a prototype of async function. Then type check is simply typeof arg === 'function' as seen here.

  • You need to define "what is a function" first
  • If you understand it as an instance of some class then you can use for example arg instanceof Function which returns a boolean
  • If you wish to see what the function inherits from then you could check its prototype
  • If you define anything that can be called a function - check if it is callable
  • There are still some issues with that :(
// It doesn't really matter if you use named function or not - but that is cool to know that it can have a name :)
let f = function aNamedFunction(){console.log('hello')};
f.prototype = null;
console.log(f instanceof Function, typeof f); // true, function
f.__proto__ = null;
console.log(f instanceof Function); // false, function
console.log(Object.getOwnPropertyNames(f)); // prototype, length, name
f(); // 'hello'

To summarize: The typeof arg === 'function' seems pretty good (though there are few fancy scenarios where it would fail).

1 Comment

Function specific introspection is even more complex than what you mentioned above. Few cases can be solved directly. The ones not being detectable have to be looked up from configs. The majority can be deduced by combining both approaches, applying including/excluding strategies. Detecting a good old ES3 function e.g. reads like that ... is a function type and has a writable prototype and is neither generator nor class.
0

Becareful about this :

typeof Object === "function" // true.
typeof Array  === "function" // true

1 Comment

Object and Array are both constructors, even though they share some static methods you might wanna use, it's highly unlikely anybody's going to check their types like that. Are there any reasons that could happen? I currently can't come out with any except for programmer's error.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.