Как определить, определена ли функция JavaScript

StackOverflow https://stackoverflow.com/questions/85815

  •  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();
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top