Проверка, является ли переменная функцией
Я столкнулся с проблемой проверки типа переменной в JavaScript. У меня есть переменная, определенная следующим образом:
var a = function() {/* Statements */};
Мне нужна функция, которая проверяет, является ли тип переменной "функцией". То есть, я хочу реализовать что-то вроде этого:
function foo(v) {
if (v is function type?) {
/* do something */
}
};
foo(a);
Как мне проверить, является ли переменная a
типом Function
в описанном выше формате?
5 ответ(ов)
В данном фрагменте кода проверяется, является ли переменная v
функцией. Если она действительно является функцией (то есть тип v
равен 'function'
), то выполняется блок кода, в котором указано // do something
. Этот подход позволяет избежать ошибок, связанных с вызовом не функции, и гарантирует, что код в этом блоке будет выполнен только в том случае, если v
соответствует ожидаемому типу.
Пример использования:
if (typeof v === 'function') {
v(); // вызовем функцию v, если она действительно функцией
} else {
console.error('Переменная v не является функцией');
}
Таким образом, данная проверка – хороший способ сделать код более устойчивым и избежать потенциальных проблем на этапе выполнения.
Конечно, способ с использованием библиотеки Underscore более эффективен, но лучший способ проверки, когда эффективность не является критичным фактором, описан на странице Underscore, ссылку на которую привел @Paul Rosania.
Вдохновленный Underscore, финальная версия функции isFunction выглядит следующим образом:
function isFunction(functionToCheck) {
return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]';
}
Примечание: Это решение не сработает для асинхронных функций, генераторов или проксированных функций. Пожалуйста, обратите внимание на другие ответы для более современных решений.
Существует несколько способов, поэтому я кратко подведу итоги:
Лучший способ:
function foo(v) { if (v instanceof Function) {/* делаем что-то */} };
Это наиболее производительное (без сравнений строк) и элегантное решение — оператор
instanceof
поддерживается в браузерах уже очень давно, так что не беспокойтесь — это будет работать даже в IE 6.Следующий лучший способ:
function foo(v) { if (typeof v === "function") {/* делаем что-то */} };
Недостаток
typeof
заключается в том, что он подвержен тихим сбоям, что плохо. Если вы допустите опечатку (например, "finction"), то в этом случаеif
просто вернет false, и вы не узнаете о вашей ошибке до более позднего момента в коде.Следующий по качеству способ:
function isFunction(functionToCheck) { var getType = {}; return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]'; }
У этого варианта нет преимуществ перед решениями #1 или #2, но он гораздо менее читаем. Улучшенная версия выглядит так:
function isFunction(x) { return Object.prototype.toString.call(x) == '[object Function]'; }
Тем не менее, она все еще менее семантична, чем решение #1.
@grandecomplex: Ваше решение довольно многословно. Было бы гораздо понятнее, если бы его записать так:
function isFunction(x) {
return Object.prototype.toString.call(x) === '[object Function]';
}
Для более широкой поддержки браузерами и добавления проверки на асинхронные функции, можно использовать следующий код:
const isFunction = value => value ? (Object.prototype.toString.call(value) === "[object Function]" || "function" === typeof value || value instanceof Function) : false;
Затем вы можете протестировать его следующим образом:
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
Таким образом, ваша функция isFunction
будет корректно определять, является ли переданное значение функцией, включая как обычные, так и асинхронные функции.
Где найти документацию по форматированию даты в JavaScript?
В чем разница между String.slice и String.substring?
Проверка соответствия строки регулярному выражению в JS
Существует ли ссылка на "последнюю" библиотеку jQuery в Google APIs?
Как создать диалог с кнопками "Ок" и "Отмена"