1223

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?

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
Jesufer Vn
  • 13,200
  • 6
  • 20
  • 26

21 Answers21

2248
if (typeof v === 'function') {
    // do something
}
Pwnstar
  • 2,333
  • 2
  • 29
  • 52
selbie
  • 100,020
  • 15
  • 103
  • 173
  • 59
    Just watch out for a few things like `typeof Object`, `typeof Date`, and `typeof String`, which all return `'function'` too. – Dave Ward May 14 '11 at 06:21
  • 450
    @Dave, I'm not sure what the problem is since those are functions. – Matthew Crumley May 14 '11 at 15:41
  • 21
    What is the difference with `if (v instanceOf Function)`? – mquandalle Sep 17 '13 at 23:38
  • 15
    @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. – rvighne Feb 01 '14 at 00:18
  • 16
    unlike the accepted answer this works for async functions too. For an `asyncfunctionToCheck`, `getType.toString.call(functionToCheck)==='[object AsyncFunction]'` where as `typeof asyncfunctionToCheck === 'function'` – TDreama Nov 04 '17 at 15:45
  • 5
    I don't understand why this is not the selected answer, as every object of type function returns this type correctly by simply using the "typeof" ability of JS... – TheCuBeMan Jul 28 '19 at 09:03
  • 1
    What's the point to use "===" instead of simply "=="? Doesn't [typeof](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof) always return a string? – ebk Nov 27 '19 at 11:51
  • 3
    @ebk - That's how I originally had it. However, JavaScript type coercion can be dangerous, so `===` is a best practice. – selbie Nov 27 '19 at 21:07
  • Compatibility matrix: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof – Erdal G. Dec 04 '20 at 10:41
  • 3
    @MatthewCrumley - I know that this was years ago but it is clear that use cases exist having a need for semantic differentiation between a "function" and, for example, a "Date", which I am sure is what Dave Ward is referring to. – Pancho Apr 30 '21 at 10:45
  • @Pancho `Date`, `Object`, and `String` are all functions, so the differentiation is there. – Melab May 02 '21 at 21:02
  • 3
    @Melab - Only if you actively know they are also functions - which on the face of it is less than obvious. I can only repeat that Dave Ward's observation has significant value for those who may otherwise be taken unawares by JS internal implementation characteristics. I will further note that "differentiation by name" is an inherently fallible approach as it requires a comprehensive knowledge of "all language names to exclude", both current and future. – Pancho May 03 '21 at 06:26
448

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.

Janne Annala
  • 25,928
  • 8
  • 31
  • 41
Alex Grande
  • 7,929
  • 1
  • 26
  • 30
  • 1
    There might be someone who has made more extensive research on the matter, but [have a look at the results of revision 4 of the jsperf with simple "result verification"](http://jsperf.com/alternative-isfunction-implementations/4). `isFunctionA` shows an implementation difference compared to the other methods. – Joel Purra Feb 02 '12 at 18:41
  • 30
    With [updated performance tests](http://jsperf.com/alternative-isfunction-implementations/9) 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. – Justin Warkentin Oct 03 '12 at 18:04
  • 7
    Regarding the part: *typeof should only be used for checking if variables or properties are undefined.* At http://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 – Konrad Madej Aug 20 '13 at 11:05
  • 13
    Alex, I'm curious why you say typeof should only be uset to check for undefined. It's name suggests it's purpose is to check the type of something, not just whether it exists. Are there technical issues or problems that can arise when using it to do type checking, or is it more of a preference? If there are caveats it would be good to list them so others can avoid tripping over them. – jinglesthula Jan 15 '14 at 19:07
  • Unfortunately, typeof can produce unusual results if you aren't careful. For instance, typeof [] // "object". Typeof certainly can be used to check the type, but be careful. – Alex Grande Apr 28 '14 at 17:46
  • 1
    I'd like to understand why is it best. Does the other way miss some cases? If it does not, why is not the most performant solution the best one? – František Žiačik Jun 15 '15 at 07:53
  • can someone please explain me the meaning of this string? what does {}.toString does? And {}.toString.call(functionToCheck)? – Don Diego Oct 18 '18 at 09:19
  • 1
    I'm wondering how this answer gets so up-votes as when I test this in chrome, i get an exception: `Uncaught SyntaxError: Unexpected token .` even the `{}.toString` will cause an exception! – S.Serpooshan Nov 11 '18 at 09:16
  • 1
    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. – ICW Dec 12 '19 at 20:48
  • 8
    Please continue scrolling to find a much easier solution. – jlh Feb 11 '20 at 15:14
  • 1
    Update 9 years later: this will not work on recent versions of IOS when the function is behind a Proxy. – Aaron Butacov Mar 16 '20 at 14:58
  • @S.Serpooshan You need to enclose this expression in parentheses. The code in the answer doesn’t have syntax errors. `{}` is a block if not in expression context. See [Why does `{} == null` give a SyntaxError?](https://stackoverflow.com/q/53306680/4642212). – Sebastian Simon Mar 14 '21 at 03:52
  • @SebastianSimon thanks, i edited the code. It is funny that `{}.toString` throws an exception (as i checked in chrome) but `({}).toString` or even `({}.toString)` are OK! – S.Serpooshan Mar 14 '21 at 18:48
  • @S.Serpooshan Again, the code in the answer was fine. `{` _at the start of a statement_ is interpreted as a block. That’s why this code _alone_ doesn’t work in your console. In the answer, `{` is _not_ at the start of the statement; it’s in the middle of the expression, as part of the second operand to `&&`, where it cannot be interpreted as a block, but as an object literal, as was correctly intended. The post I linked should explain all this. – Sebastian Simon Mar 14 '21 at 20:35
  • @SebastianSimon Thanks for explanation. I think, it is more safe to embrace the `{}` between parenthesis `({})` to keep it ok all the time. consider when you are changing your code and you are not remember that `{}` should not be at begining of line.. – S.Serpooshan Mar 15 '21 at 16:49
194

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

AymDev
  • 6,626
  • 4
  • 29
  • 52
dalimian
  • 2,066
  • 1
  • 12
  • 6
  • 16
    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). – MaxArt Aug 15 '14 at 19:34
  • 4
    Regarding your point about typos: any code which has this typo is likely to fail quickly/ is no more apparent than any other bugs based on typos. typeof === "function" is the cleanest solution. Additionally your “best” solution where you use `instanceof` does not take into account multiple globals, such as a check across frames, and can return false negatives. – brainkim Apr 12 '18 at 17:30
  • The typo story was just to mention the harmfulness of magic strings. Avoid magic strings where you can. – ThaJay Oct 05 '21 at 11:55
144

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

EscapeNetscape
  • 2,892
  • 1
  • 33
  • 32
Paul Rosania
  • 9,823
  • 2
  • 20
  • 18
  • Is there any particular reason to use this approach than `typof`? – sv_in May 14 '11 at 06:13
  • 1
    Underscore's version is *much* faster in most browsers. See: http://jsperf.com/alternative-isfunction-implementations – Paul Rosania May 14 '11 at 06:16
  • 22
    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. – studgeek Aug 26 '11 at 18:57
  • 3
    @PaulRosania Stumbled upon these performance tests earlier today, and [updated them with verification plus more test data as revision 4](http://jsperf.com/alternative-isfunction-implementations/4) - please run it to increase browser test coverage. It's slower in operations per second (due to the many tests), but it also shows one implementation difference (open your javascript console and reload page, there might be logged error messages). Note: Revision 3 added isFunctionD (based on only `typeof == "function"`) - and it seems to be **much faster** than Underscore's "fast" version. – Joel Purra Feb 02 '12 at 18:35
  • 8
    This answer is a bit misleading now, as Underscore.js is now on [revision 12](http://jsperf.com/alternative-isfunction-implementations/12), not the above-referenced revision 4, of its test of alternative `isFunction()` implementations. It currently uses something very close to what [dandean](http://stackoverflow.com/users/374773/dandean) suggested. – Jonathan Eunice May 04 '13 at 03:09
  • 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`. – cpcallen Sep 15 '17 at 15:15
  • 3
    Underscore.js now uses `typeof obj == 'function' || false`. ([Source](https://github.com/jashkenas/underscore/blob/943977e34e2279503528a71ddcc2dd5f96483945/modules/isFunction.js#L11)) – Emile Bergeron Apr 29 '21 at 19:41
93

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);
Cesar Loachamin
  • 2,740
  • 4
  • 25
  • 33
61

@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]';
}
dandean
  • 1,431
  • 1
  • 12
  • 7
52

const foo = function() {};
if (typeof foo === 'function') {
  console.log('is function')
}
Teocci
  • 7,189
  • 1
  • 50
  • 48
wsc
  • 916
  • 7
  • 10
52

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);

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
Alireza
  • 100,211
  • 27
  • 269
  • 172
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
Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
  • 1
    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`. – snarf Mar 13 '21 at 22:23
13

An other simply way:

var fn = function () {}
if (fn.constructor === Function) {
  // true
} else {
  // false
}
GuillaumeL
  • 509
  • 3
  • 14
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.

Damaged Organic
  • 8,175
  • 6
  • 58
  • 84
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.

saeta
  • 4,048
  • 2
  • 31
  • 48
6

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%.

Teocci
  • 7,189
  • 1
  • 50
  • 48
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
Marcus Junius Brutus
  • 26,087
  • 41
  • 189
  • 331
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.

Azmisov
  • 6,493
  • 7
  • 53
  • 70
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

Danny Mor
  • 1,143
  • 12
  • 12
3

you should use typeOf operator in js.

var a=function(){
    alert("fun a");
}
alert(typeof a);// alerts "function"
Rajesh Paul
  • 6,793
  • 6
  • 40
  • 57
3

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

var util = require('util');
util.isFunction('foo');
amdixon
  • 3,814
  • 8
  • 25
  • 34
moklick
  • 116
  • 3
2

if you are looking for a simple solution:

 function isFunction(value) {
   return value instanceof Function
}
De Bonheur
  • 742
  • 10
  • 13
0

Becareful about this :

typeof Object === "function" // true.
typeof Array  === "function" // true
Yassine CHABLI
  • 3,459
  • 2
  • 23
  • 43
  • 1
    `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. – Shape Dec 21 '21 at 21:41
0

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
Jannis Ioannou
  • 1,692
  • 1
  • 14
  • 17