如何检查JavaScript中是否存在函数?


533

我的代码是

function getID( swfID ){
     if(navigator.appName.indexOf("Microsoft") != -1){
          me = window[swfID];
     }else{
          me = document[swfID];
     }
}

function js_to_as( str ){
     me.onChange(str);
}

但是,有时我onChange无法加载。萤火虫错误

me.onChange不是一个函数

我想优雅地降级,因为这不是程序中最重要的功能。typeof给出相同的错误。

关于如何确保它存在然后仅执行的任何建议onChange

(除了尝试捕获一项工作以外,以下任何一种方法)


1
@SteveChambers我已经做到了。谢谢你提醒我。
Alec Smart


捕获异常。检查我的答案
Matteus Barbosa

Answers:


1222

尝试这样的事情:

if (typeof me.onChange !== "undefined") { 
    // safe to use the function
}

或更好(根据UpTheCreek的评论)

if (typeof me.onChange === "function") { 
    // safe to use the function
}

248
==='功能'会比!='未定义'好
UpTheCreek

3
@James,因为该语句实际上undefined在JavaScript中引发了异常。我尝试过这个。
Mike Perrenoud 2013年

8
@UpTheCreek,由于一般版本的IE将某些功能视为对象,例如,这将是一个危险的通用解决方案typeof window.alert === 'object'
Noyo 2013年

1
为什么不只是使用if (me.onChange) { // do something }
BornToCode 2014年

3
@BornToCode,因为这样me.onChange可以是任何要求值的东西true,不一定是函数(例如,它可以是布尔值,字符串等)。例如,请参见jsfiddle.net/j5KAF/1
Ohad Schneider

108

我有这个问题。

if (obj && typeof obj === 'function') { ... }

如果碰巧未定义obj,则会不断抛出引用错误。

最后,我执行了以下操作:

if (typeof obj !== 'undefined' && typeof obj === 'function') { ... }

一位同事向我指出的是检查,如果它的!== 'undefined',然后=== 'function'是多余的,当然。

更简单:

if (typeof obj === 'function') { ... }

更清洁,效果很好。


1
有人知道为什么第一个代码片段会抛出ReferenceError吗?对我来说这似乎不合逻辑。
saidfagan


这对我
有用

1
有什么动机为什么typeof obj =='function'不够?;-)提醒:严格相等性测试运算符仅在静态操作数为空,null或0或经受任何此类转换游戏时才有意义。
Fabien Haddadi

16

如果您正在使用eval将字符串转换为函数,并且想要检查此eval'd方法是否存在,则需要在eval中使用typeof和函数字符串:

var functionString = "nonexsitantFunction"
eval("typeof " + functionString) // returns "undefined" or "function"

不要颠倒这个,在eval上尝试使用typeof。如果执行ReferenceError,将抛出:

var functionString = "nonexsitantFunction"
typeof(eval(functionString)) // returns ReferenceError: [function] is not defined

21
eval ==邪恶;)
雪人2012年

1
这可能很邪恶,但是当函数名称位于变量中时,这将非常有用。
路加·考辛斯

8
您无需评估即可执行此操作。示例:var a = 'alert'; window[a]('it works');
zennin

15

怎么样:

if('functionName' in Obj){
    //code
}

例如

var color1 = new String("green");
"length" in color1 // returns true
"indexOf" in color1 // returns true
"blablabla" in color1 // returns false

或根据您的情况:

if('onChange' in me){
    //code
}

请参阅MDN文档


但是此解决方案并非每次都有效:(例如,如果我想知道它存在lastIndexOf()于字符串中(我们知道,也就是说,从理论上来说),typeof String().lastIndexOf === "function"这是对的,但是'lastIndexOf' in String是错误的
。– iiic

10

尝试typeof-寻找一个功能'undefined'不存在'function'JSFiddle用于此代码

function thisishere() {
    return false;
}
alert("thisishere() is a " + typeof thisishere);
alert("thisisnthere() is " + typeof thisisnthere);

或者,如果:

if (typeof thisishere === 'function') {
    // function exists
}

或带有返回值的一行:

var exists = (typeof thisishere === 'function') ? "Value if true" : "Value if false";
var exists = (typeof thisishere === 'function') // Returns true or false

9

没看到这个建议:me.onChange && me.onChange(str);

基本上,如果me.onChange是未定义的(如果尚未启动,它将是未定义的),则它将不执行后一部分。如果me.onChange是一个函数,它将执行me.onChange(str)。

您甚至可以走得更远,并执行以下操作:

me && me.onChange && me.onChange(str);

万一我也是异步的。


5
//Simple function that will tell if the function is defined or not
function is_function(func) {
    return typeof window[func] !== 'undefined' && $.isFunction(window[func]);
}

//usage

if (is_function("myFunction") {
        alert("myFunction defined");
    } else {
        alert("myFunction not defined");
    }

您的解决方案尚不清楚,因为它包含jQUery,我认为此刻很奇怪,因此在进行简单测试时会引发错误。
T.Todua 2015年

@tazotodua是自我解释功能。如果您想在没有jquery的情况下使用。只需删除&&部分。这是检查和避免错误的额外条件。
Muhammad Tahir 2015年

左边的条件是否&&照顾了jQuery isFunction右边的条件所&&不能解决的问题?
SantiBailors

5

对我来说,最简单的方法是:

function func_exists(fname)
{
  return (typeof window[fname] === 'function');
}

这是正确的答案,因为它是乱七八糟的..我会说这样更好,但这if ((typeof window["function_name"] !== 'undefined') && ((typeof window["function_name"] === 'function'))) { return true; } else { return false; }只是个小调整
Heelis先生18/12/20

4

我将更进一步以确保该属性确实是一个函数

function js_to_as( str ){
     if (me && me.onChange && typeof me.onChange === 'function') {
         me.onChange(str);
     }
}

3
function js_to_as( str ){
     if (me && me.onChange)
         me.onChange(str);
}

3

我喜欢使用这种方法:

function isFunction(functionToCheck) {
  var getType = {};
  return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
}

用法:

if ( isFunction(me.onChange) ) {
    me.onChange(str); // call the function with params
}


3
function function_exists(function_name)
{
    return eval('typeof ' + function_name) === 'function';
}
alert(function_exists('test'));
alert(function_exists('function_exists'));

要么

function function_exists(func_name) {
  //  discuss at: http://phpjs.org/functions/function_exists/
  // original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // improved by: Steve Clay
  // improved by: Legaev Andrey
  // improved by: Brett Zamir (http://brett-zamir.me)
  //   example 1: function_exists('isFinite');
  //   returns 1: true

  if (typeof func_name === 'string') {
    func_name = this.window[func_name];
  }
  return typeof func_name === 'function';
}

1
请一些解释。
Gufran Hasan '18

在两种情况下,只需使用函数参数名称调用function_exists来检查是否存在,则返回bool。
Mohammad Lotfi '18

3

把双感叹号,即!要检查的函数名称之前。如果存在,它将返回true。

function abc(){
}
!!window.abc; // return true
!!window.abcd; // return false

3

简而言之:捕获异常。

我真的很惊讶,目前还没有人回答或评论Exception Catch。

详细信息:这是一个示例,在该示例中,我尝试匹配以mask_为前缀并以字段“ name”为后缀的函数。当JavaScript未找到该函数时,它应该引发一个ReferenceError,您可以根据需要在catch部分处理该错误。

function inputMask(input) {
  try {
    let maskedInput = eval("mask_"+input.name);

    if(typeof maskedInput === "undefined")
        return input.value;
    else
        return eval("mask_"+input.name)(input);

  } catch(e) {
    if (e instanceof ReferenceError) {
      return input.value;
    }
  }
}


2

无条件

me.onChange=function(){};

function getID( swfID ){
     if(navigator.appName.indexOf("Microsoft") != -1){
          me = window[swfID];
     }else{
          me = document[swfID];
     }
}

function js_to_as( str ){
     me.onChange(str);
}

2

我会怀疑me没有正确分配onload。

将get_ID调用移到onclick事件中应该注意这一点。

显然,您可以如前所述进一步陷井:

function js_to_as( str) {
  var me = get_ID('jsExample');
  if (me && me.onChange) {
    me.onChange(str);
  }
}

2

我总是这样检查:

if(!myFunction){return false;}

只需将其放在使用此功能的任何代码之前


2

我遇到的情况是,函数名称根据添加到函数名称中的变量(在这种情况下为var'x')而变化。这有效:

if ( typeof window['afunction_'+x] === 'function' ) { window['afunction_'+x](); } 

2

这个简单的jQuery代码应该可以解决问题:

if (jQuery.isFunction(functionName)) {
    functionName();
}

2

我已经尝试了接受的答案;然而:

console.log(typeof me.onChange);

返回“未定义”。我注意到规范说明了一个名为“ onchange”而不是“ onChange”的事件(请注意camelCase)。

将原始可接受的答案更改为以下内容对我有用:

if (typeof me.onchange === "function") { 
  // safe to use the function
}


2

我也一直在寻找解决这个问题的优雅方法。经过深思熟虑,我发现这种方法最好。

const func = me.onChange || (str => {}); func(str);


如果要最小化,也可以执行以下操作:(me.onChange||(_=>_))()如果函数存在,将执行该函数,否则将不执行任何操作。
JSideris

最好me.onChange && me.onChange()避免定义一个void函数。
necrifede

2

现代Java抢救!

一长串的答案可能不会很大,但是现在可以通过新的Optional Chaining语法在语言级别解决*

me.onChange?.(str)

就这么简单- onChange仅在存在时才被调用

如果onChange不存在,则什么也不会发生,并且表达式会返回undefined-因此,如果它具有返回值(否则将使用该返回值),则可以!== undefined在继续之前简单地检查该值。

边缘的情况下警告-如果onChange 确实存在,但不是一个功能,你会得到一个TypeError。就像您所期望的那样,它与尝试将任何非函数作为函数调用相同,但是值得明确指出的是,可选链接并不能起到任何作用。

*嗯,从技术上讲,“可选链接”仍是TC39第4阶段建议,因此尚未在ECMAScript规范中提出,但第4阶段意味着已完成定稿,并且基本上可以保证将其包括在内,它只是在等待新版本的发布。您可以立即通过Babel在其最终版本中使用该语法,并确信它不会更改。甚至在Typescript中!


1

这里是一个工作和用于检查简单的解决方案的功能的存在动态地触发该功能的另一个功能;

触发功能

function runDynamicFunction(functionname){ 

    if (typeof window[functionname] == "function") { //check availability

        window[functionname]("this is from the function it"); // run function and pass a parameter to it
    }
}

现在您可以像这样使用php动态生成函数

function runThis_func(my_Parameter){

    alert(my_Parameter +" triggerd");
}

现在您可以使用动态生成的事件来调用该函数

<?php

$name_frm_somware ="runThis_func";

echo "<input type='button' value='Button' onclick='runDynamicFunction(\"".$name_frm_somware."\");'>";

?>

您需要的确切HTML代码是

<input type="button" value="Button" onclick="runDynamicFunction('runThis_func');">

0
    function sum(nb1,nb2){

       return nb1+nb2;
    }

    try{

      if(sum() != undefined){/*test if the function is defined before call it*/

        sum(3,5);               /*once the function is exist you can call it */

      }

    }catch(e){

      console.log("function not defined");/*the function is not defined or does not exists*/
    }

0

然后是这个...

( document.exitPointerLock || Function )();

师父,您好,但是您对捕获异常有何看法?检查我的答案
Matteus Barbosa

嗨,谢谢你的来信。您的解决方案令人钦佩。我尝试尽可能避免或尽可能避免使用“尝试捕获”范例,或者它可能是由第三方援助隐含/强加的。出于各种原因,人们也常常不喜欢“ Eval”,因为它就像试图抓住另一个包装纸一样,因此会造成时间延迟。评估的替代方法也可能“抛出”。我认为“新函数(parms,body)”可能会向您抛出错误,但是我想对我来说,下一个问题是速度比较,而这仅仅是最大程度地减少代码大小(对我而言意味着更快)。[嗯,这看起来很新。我没有尝试过[jsben.ch]
大师詹姆斯(James)

mmm有趣的一点是关于调用新功能。随时将您的更改建议提交给我的答案。非常感谢
Matteus Barbosa

是的,我的意思是即使在bash中使用'source myScript.sh'也会让您通过别名等“导出”。这就像类和库一直是所有代码的固有属性。如果没有确定,您应该有一个js解释器检查代码。我在一个函数中构建了一个函数,这是另一个有趣的挑战,可以帮助您理解最简单的公理性质的代码,甚至运行时也不是任何人都无法承受的。
大师詹姆斯

0

试试这个:

Window.function_exists=function(function_name,scope){
//Setting default scope of none is provided
If(typeof scope === 'undefined') scope=window;
//Checking if function name is defined
If (typeof function_name === 'undefined') throw new 
Error('You have to provide an valid function name!');
//The type container
var fn= (typeof scope[function_name]);
//Function type
If(fn === 'function') return true;
//Function object type
if(fn.indexOf('function')!== false) return true; 
return false;
}

请注意,我已经用手机编写了此代码,可能包含一些大写问题和/或所需的其他更正,例如函数名称

如果您想要像PHP这样的函数来检查var是否已设置:

Window.isset=function (variable_con){
If(typeof variable_con !== 'undefined') return true;
return false;
}

0

为了说明前面的答案,这里是一个快速的JSFiddle片段:

function test () {
console.log()

}

console.log(typeof test) // >> "function"

// implicit test, in javascript if an entity exist it returns implcitly true unless the element value is false as :
// var test = false
if(test){ console.log(true)}
else{console.log(false)}

// test by the typeof method
if( typeof test === "function"){ console.log(true)}
else{console.log(false)}


// confirm that the test is effective : 
// - entity with false value
var test2 = false
if(test2){ console.log(true)}
else{console.log(false)}

// confirm that the test is effective :
// - typeof entity
if( typeof test ==="foo"){ console.log(true)}
else{console.log(false)}

/* Expected :
function
true 
true 
false
false
*/


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.