var fn = function(){};
var obj = {};
var objNull = null;
var unknown; // undefined
var isFuncTrue = typeof fn === 'function';
var isFuncFalse = typeof obj === 'function';
var isFuncFalse2 = typeof objNull === 'function';
var isFuncFalse3 = typeof unknown === 'function';
var isFuncTrue = fn && 'call' in fn;
var isFuncFalse = obj && 'call' in obj;
var isFuncFalse2 = objNull && 'call' in objNull;
var isFuncFalse3 = unknown && 'call' in unknown;
var isFuncTrue = !!fn?.call;
var isFuncFalse = !!obj?.call;
var isFuncFalse2 = !!objNull?.call;
var isFuncFalse3 = !!unknown?.call;
var isFuncTrue = fn?.call != null;
var isFuncFalse = obj?.call != null;
var isFuncFalse2 = objNull?.call != null;
var isFuncFalse3 = unknown?.call != null;
var isFuncTrue = fn?.call != void 0;
var isFuncFalse = obj?.call != void 0;
var isFuncFalse2 = objNull?.call != void 0;
var isFuncFalse3 = unknown?.call != void 0;
var isFuncTrue = fn?.call != undefined;
var isFuncFalse = obj?.call != undefined;
var isFuncFalse2 = objNull?.call != undefined;
var isFuncFalse3 = unknown?.call != undefined;
--enable-precise-memory-info
flag.
Test case name | Result |
---|---|
typeof function | |
call in function | |
!!fn?.call | |
fn?.call != null | |
fn?.call != void 0 | |
isFuncTrue = fn?.call != undefined; |
Test name | Executions per second |
---|---|
typeof function | 9300926.0 Ops/sec |
call in function | 6173735.5 Ops/sec |
!!fn?.call | 6911329.0 Ops/sec |
fn?.call != null | 9090097.0 Ops/sec |
fn?.call != void 0 | 8914031.0 Ops/sec |
isFuncTrue = fn?.call != undefined; | 2929500.0 Ops/sec |
What is being tested?
The provided benchmark tests the performance of different ways to check if a value is a function in JavaScript. The test cases compare the following approaches:
typeof
operator (typeof fn === 'function'
)call
property using the in
operator ('call' in obj
)!!fn?.call
)()
is not null or undefined (fn?.call != null
, fn?.call != void 0
, and fn?.call != undefined
)Options comparison
Each test case compares two approaches:
For example, in the "typeof function" test case, the first approach uses typeof fn === 'function'
, while the second approach uses 'call' in fn
.
Pros and cons of each approach
typeof
operator: This approach is simple and widely supported. However, it can be slower than other approaches because it involves a string comparison.call
property using in
operator: This approach is fast because it only checks if the property exists, but it may not work for all types of values (e.g., strings).!!fn?.call
): This approach is concise and modern, but it requires support for optional chaining in older browsers.()
is not null or undefined: This approach is simple and can be faster than using typeof
or checking for call
property, but it may not work for all types of values (e.g., objects without call
method).Library usage
None of the test cases use any external libraries.
Special JavaScript features or syntax
The benchmark uses optional chaining (!!fn?.call
) and the in
operator to check if an object has a call
property. These are modern JavaScript features introduced in ECMAScript 2018 (ES2018).
Other alternatives
Other approaches that could be used to test this benchmark include:
new Function()
): This approach is slower than checking for the existence of a call
property.Note that these alternative approaches may not be as efficient or concise as the ones being tested, and may not work in all cases.