Как определить, определена ли функция JavaScript
-
01-07-2019 - |
Вопрос
Как вы определяете, определена ли функция в JavaScript?
Я хочу сделать что-то вроде этого
function something_cool(text, callback) {
alert(text);
if( callback != null ) callback();
}
Но это дает мне
обратный вызов - это не функция
ошибка, когда обратный вызов не определен.
Решение
typeof callback === "function"
Другие советы
Все текущие ответы используют буквальную строку, которую я предпочитаю не иметь в своем коде, если это возможно - это не так (и обеспечивает ценное семантическое значение для загрузки):
function isFunction(possibleFunction) {
return typeof(possibleFunction) === typeof(Function);
}
Лично я стараюсь уменьшить количество строк, зависающих в моем коде...
Кроме того, хотя я и осознаю, что typeof
является оператором, а не функцией, поэтому нет особого вреда в использовании синтаксиса, который делает его похожим на последнюю.
if (callback && typeof(callback) == "function")
Обратите внимание, что обратный вызов (сам по себе) вычисляется как false
если это так undefined
, null
, 0
, или false
.Сравнивая с null
слишком специфичен.
Те методы, которые позволяют определить, реализована ли функция, также терпят неудачу, если переменная не определена, поэтому мы используем что-то более мощное, поддерживающее получение строки:
function isFunctionDefined(functionName) {
if(eval("typeof(" + functionName + ") == typeof(Function)")) {
return true;
}
}
if (isFunctionDefined('myFunction')) {
myFunction(foo);
}
Новичок в JavaScript, я не уверен, изменилось ли поведение, но решение, данное Джейсоном Бантингом (6 лет назад), не будет работать, если возможная функция не определена.
function isFunction(possibleFunction) {
return (typeof(possibleFunction) == typeof(Function));
}
Это приведет к появлению ReferenceError: possibleFunction is not defined
ошибка, поскольку движок пытается разрешить функцию symbol possibleFunction (как указано в комментариях к ответу Джейсона)
Чтобы избежать такого поведения, вы можете передать только имя функции, которую вы хотите проверить, существует ли она.Итак
var possibleFunction = possibleFunction || {};
if (!isFunction(possibleFunction)) return false;
Это устанавливает переменную либо в качестве функции, которую вы хотите проверить, либо в качестве пустого объекта, если она не определена, и таким образом позволяет избежать проблем, упомянутых выше.
Попробуй:
if (typeof(callback) == 'function')
Я мог бы это сделать
try{
callback();
}catch(e){};
Я знаю, что есть общепринятый ответ, но никто этого не предлагал.Я не совсем уверен, подходит ли это под описание идиоматического, но это работает во всех случаях.
В более новых движках JavaScript a finally
может быть использован вместо этого.
if ('function' === typeof callback) ...
typeof(callback) == "function"
function something_cool(text, callback){
alert(text);
if(typeof(callback)=='function'){
callback();
};
}
Попробуй это:
callback instanceof Function
Если вы посмотрите на Источник из библиотеки, о которой упоминал @Venkat Sudheer Редди Эдама, underscorejs, вы можете увидеть это:
_.isFunction = function(obj) {
return typeof obj == 'function' || false;
};
Это всего лишь моя ПОДСКАЗКА, ПОДСКАЗКА-ответ:>
Попробуй:
if (!(typeof(callback)=='undefined')) {...}
Если вы используете http://underscorejs.org, у вас есть:http://underscorejs.org/#isFunction
_.isFunction(callback);
Я искал, как проверить, была ли определена функция jQuery, и мне было нелегко ее найти.
Возможно, это может понадобиться ;)
if(typeof jQuery.fn.datepicker !== "undefined")
Если callback()
вы вызываете функцию не только один раз, вы могли бы инициализировать аргумент для повторного использования:
callback = (typeof callback === "function") ? callback : function(){};
Например:
function something_cool(text, callback) {
// Initialize arguments
callback = (typeof callback === "function") ? callback : function(){};
alert(text);
if (text==='waitAnotherAJAX') {
anotherAJAX(callback);
} else {
callback();
}
}
Ограничение заключается в том, что он всегда будет выполнять аргумент обратного вызова, хотя он и не определен.
Для глобальных функций вы можете использовать эту вместо eval
предложено в одном из ответов.
var global = (function (){
return this;
})();
if (typeof(global.f) != "function")
global.f = function f1_shim (){
// commonly used by polyfill libs
};
Вы можете использовать global.f instanceof Function
тоже самое, но афаик.ценность этого Function
будет отличаться в разных фреймах, поэтому он будет корректно работать только с одним фреймовым приложением.Вот почему мы обычно используем typeof
вместо этого.Обратите внимание, что в некоторых средах могут возникать аномалии с typeof f
тоже, напримерс помощью MSIE 6-8 некоторые функции, например alert
имел тип "объект".
По локальным функциям вы можете использовать ту, что указана в принятом ответе.Вы также можете проверить, является ли функция локальной или глобальной.
if (typeof(f) == "function")
if (global.f === f)
console.log("f is a global function");
else
console.log("f is a local function");
Чтобы ответить на вопрос, пример кода работает у меня без ошибок в последних версиях браузера, поэтому я не уверен, в чем была проблема с ним:
function something_cool(text, callback) {
alert(text);
if( callback != null ) callback();
}
Примечание:Я бы использовал callback !== undefined
вместо того, чтобы callback != null
, но они делают почти то же самое.
Большинство, если не все предыдущие ответы, имеют побочные эффекты при вызове функции
вот лучшая практика
у вас есть функция
function myFunction() {
var x=1;
}
//direct way
if( (typeof window.myFunction)=='function')
alert('myFunction is function')
else
alert('myFunction is not defined');
//byString
var strFunctionName='myFunction'
if( (typeof window[strFunctionName])=='function')
alert(s+' is function');
else
alert(s+' is not defined');
Однострочное решение:
function something_cool(text, callback){
callback && callback();
}