Тим, хто цікавиться функціональним стилем або шукає більш виразного підходу до використання в метапрограмуванні (наприклад, перевірка типів), може бути цікаво побачити бібліотеку 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 ));
Однак зауважте, що це рішення може виявити меншу ефективність, ніж інші доступні опції через велике використання функцій вищого порядку.