There are different types of functions in modern-ish JavaScript: regular, async, and generator functions. However, typeof returns "function" for all of them. One way (the only?) to differentiate between them is by using toString.call(myFunc). For example:

function a() {return 1;}
async function b() {return 2;}
function* c() {return 3;}

console.log(typeof a, toString.call(a), a());
// outputs: function [object Function] 1

console.log(typeof b, toString.call(b), await b());
// outputs: function [object AsyncFunction] 2

console.log(typeof c, toString.call(c), c().next().value);
// outputs: function [object GeneratorFunction] 3
Final thoughts

The jQuery library, before version 4 (which is not out yet, by the way), checks if an event handler for "document.ready" is a function by effectively comparing the result of toString.call(callback) to "[object Function]". This means an async function (or generator) doesn't work. Which was a ton of fun to debug.

To make matters worse, since the new syntax for functions that return promises is just supposed to be "syntactic sugar", these two functions are functionally equivalent, which makes it infuriating that there's a way to tell them apart at all:

async function a() {return 1;}
function b() {return new Promise(resolve => resolve(1));}
Previous on Javascript