Ответ 1
typeof callback === "function"
Как определить, определена ли функция в 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
, поскольку движок пытается разрешить символ possibleFunction (как указано в комментариях к ответу Джейсона)
Чтобы избежать такого поведения, вы можете передать только имя функции, которую вы хотите проверить, существует ли она. Так
var possibleFunction = possibleFunction || {};
if (!isFunction(possibleFunction)) return false;
Это устанавливает переменную как функцию, которую вы хотите проверить, или пустой объект, если она не определена, и поэтому позволяет избежать упомянутых выше проблем.
Попробуйте:
if (typeof(callback) == 'function')
typeof(callback) == "function"
if ('function' === typeof callback) ...
Я мог бы сделать
try{
callback();
}catch(e){};
Я знаю, что есть принятый ответ, но никто не предложил это. Я не совсем уверен, соответствует ли это описанию idiomatic, но это работает для всех случаев.
В более новых движках JavaScript вместо этого можно использовать finally
.
function something_cool(text, callback){
alert(text);
if(typeof(callback)=='function'){
callback();
};
}
Попробуйте:
if (!(typeof(callback)=='undefined')) {...}
Попробуйте следующее:
callback instanceof Function
Если вы посмотрите на источник в библиотеке @Venkat Sudheer Reddy Aedama, упомянутый ниже, вы можете увидеть это:
_.isFunction = function(obj) {
return typeof obj == 'function' || false;
};
Это только мой СОВЕТ, СОВЕТ ответ: >
Если вы используете 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();
}
}
Ограничение состоит в том, что он всегда будет выполнять аргумент обратного вызова, хотя он undefined.
Для глобальных функций вы можете использовать этот вариант вместо 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
, но afaik. значение 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;
}
Если вы хотите переопределить функции, лучше использовать функциональные переменные, которые определены в порядке их появления, поскольку функции определяются глобально, независимо от того, где они происходят.
Пример создания новой функции, которая вызывает предыдущую функцию с тем же именем:
A=function() {...} // first definition
...
if (typeof A==='function')
oldA=A;
A=function() {...oldA()...} // new definition
Это сработало для меня
if( cb && typeof( eval( cb ) ) === "function" ){
eval( cb + "()" );
}
Однострочное решение:
function something_cool(text, callback){
callback && callback();
}