如何判断是否定义了JavaScript函数

Aar*_*Lee 292 javascript reflection

如何判断JavaScript中的函数是否已定义?

我想做这样的事情

function something_cool(text, callback) {
    alert(text);
    if( callback != null ) callback();
}
Run Code Online (Sandbox Code Playgroud)

但它让我了

回调不是一个功能

未定义回调时出错.

Tom*_*ter 452

typeof callback === "function"
Run Code Online (Sandbox Code Playgroud)

  • 这不是一个神奇的字符串,因为在ECMA规范中精确定义了一组typeof值.虽然这个语法开头有点傻,但它是完全合理的惯用Javascript. (47认同)
  • 是的,"魔术"是一个草率,可怜的单词选择 - 我的意思是"文字字符串"而非"魔术字符串".我的错.:) (4认同)
  • @quixoto - 理解,我想我的意思是你仍然需要一个字符串 - 我宁愿没有任何更多的文字字符串乱丢我的代码而不是绝对需要; 因此,如果某个功能是某种功能,这不是我测试的理想选择. (2认同)
  • 确保删除函数上的括号,并且仅在 if 条件中使用函数名称,否则将调用该函数,而不是给出 true 或 false。 (2认同)

Jas*_*ing 234

所有当前的答案都使用了一个文字字符串,如果可能的话,我更喜欢在我的代码中没有这个字符串 - 这不会(并提供有价值的语义含义,引导):

function isFunction(possibleFunction) {
  return typeof(possibleFunction) === typeof(Function);
}
Run Code Online (Sandbox Code Playgroud)

就个人而言,我尝试减少代码中挂着的字符串数量......


此外,虽然我知道这typeof是一个操作符而不是一个函数,但使用语法使其显示为后者几乎没有什么害处.

  • 或者避免使用函数`isFunction`并执行`(typeof no_function == typeof Function)`. (8认同)
  • 我该如何使用这个功能?我已经尝试了`isFunction(not_defined))`其中`not_defined`是未定义的函数名称,而FireBug返回`not_defined未定义`这是正确的但是你的函数应该返回false并且不生成错误... (7认同)
  • @ZacharyYates解决ReferenceError的方法意味着避免使用对not-not-defined-function的引用.您可以在函数调用中执行类型检查并将结果传递给函数.http://jsfiddle.net/qNaxJ/也许不太好,但至少没有使用过字符串;) (3认同)
  • @JasonBunting如果你会那么挑剔,你真的应该使用`typeof(Function())`因为Function是一个函数; 但是Array,Object和其他内置原型也是如此(缺少一个更好的术语).如果你正在检查数组,你不会使用`typeof(array)=== typeof(Array)`; 你使用`typeof(array)=== typeof(Array())`因为如果你小心和一致,你实际上需要评估函数. (2认同)

Rob*_*ird 15

if (callback && typeof(callback) == "function")
Run Code Online (Sandbox Code Playgroud)

需要注意的是回调(本身)的计算结果为false,如果是undefined,null,0,或false.比较null过于具体.

  • @Joe,但由于短路,如果回调评估为false,则不会执行该测试. (5认同)
  • 该解决方案无法正常工作,因为第一个条件将立即引发异常。对于对象的属性,这可能有效:if(obj.callback){...} (3认同)
  • 还要注意,如果`callback`本身评估为"false-y"值,那么它的typeof可以*永远不是"函数". (2认同)

Dar*_*n G 11

使用带有函数调用的可选链,您可以执行以下操作:

function something_cool(text, callback) {
    alert(text);
    callback?.();
}
Run Code Online (Sandbox Code Playgroud)

如果callback是一个函数,它将被执行。

如果callbacknullundefined,则不会引发任何错误并且不会发生任何情况。

然而,如果callback是其他东西,例如字符串或数字,仍然会抛出 TypeError。


小智 8

如果未定义变量,那么判断函数是否实现的方法也会失败,因此我们使用了更强大的函数来支持接收字符串:

function isFunctionDefined(functionName) {
    if(eval("typeof(" + functionName + ") == typeof(Function)")) {
        return true;
    }
}

if (isFunctionDefined('myFunction')) {
    myFunction(foo);
}
Run Code Online (Sandbox Code Playgroud)


bdu*_*kes 6

尝试:

if (typeof(callback) == 'function')
Run Code Online (Sandbox Code Playgroud)

  • 嗨,不要使用“松散”比较(==),甚至要使用“===”来比较变量的类型。 (2认同)

Nec*_*oft 6

JavaScript新手我不确定行为是否已经改变,但是如果没有定义可能的函数,Jason Bunting(6年前)给出的解决方案将不起作用.

function isFunction(possibleFunction) {
  return (typeof(possibleFunction) == typeof(Function));
}
Run Code Online (Sandbox Code Playgroud)

这将引发ReferenceError: possibleFunction is not defined错误,因为引擎试图解析符号possibleFunction(如对Jason的回答中提到的那样)

要避免此行为,您只能传递要检查的函数的名称(如果存在).所以

var possibleFunction = possibleFunction || {};
if (!isFunction(possibleFunction)) return false;
Run Code Online (Sandbox Code Playgroud)

这将变量设置为要检查的函数,或者如果未定义,则将空对象设置为空对象,从而避免上述问题.


小智 5

typeof(callback) == "function"
Run Code Online (Sandbox Code Playgroud)


Que*_*les 5

我可能会

try{
    callback();
}catch(e){};
Run Code Online (Sandbox Code Playgroud)

我知道有一个公认的答案,但没有人建议这样做。我不确定这是否符合惯用语的描述,但它适用于所有情况。

在较新的 JavaScript 引擎中,finally可以使用 a 代替。