Для тех, кто интересуется функциональным стилем или ищет более выразительный подход для использования в метапрограммировании (например, проверку типов), было бы интересно увидеть библиотеку Ramda для выполнения такой задачи.
Следующий код содержит только чистые и точечные функции:
const R = require('ramda');
const isPrototypeEquals = R.pipe(Object.getPrototypeOf, R.equals);
const equalsSyncFunction = isPrototypeEquals(() => {});
const isSyncFunction = R.pipe(Object.getPrototypeOf, equalsSyncFunction);
Начиная с ES2017, async
функции доступны, поэтому мы также можем проверить их:
const equalsAsyncFunction = isPrototypeEquals(async () => {});
const isAsyncFunction = R.pipe(Object.getPrototypeOf, equalsAsyncFunction);
А затем объединить их вместе:
const isFunction = R.either(isSyncFunction, isAsyncFunction);
Конечно, функция должна быть защищена от null
и undefined
значений, чтобы сделать ее «безопасной»:
const safeIsFunction = R.unless(R.isNil, isFunction);
И полный фрагмент, чтобы подвести итог:
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 ));
Однако обратите внимание, что это решение может показывать меньшую производительность, чем другие доступные опции, из-за широкого использования функций более высокого порядка.