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

Ale*_*art 486 javascript

我按照本指南创建了一个新的JS到Flash通信.

我的代码是

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

function js_to_as( str ){
     me.onChange(str);
}
Run Code Online (Sandbox Code Playgroud)

但是,有时我onChange不加载.Firebug错误

me.onChange不是一个功能

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

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

(以下没有一种方法除了尝试抓一件作品)

And*_*are 1120

尝试这样的事情:

if (typeof me.onChange !== "undefined") { 
    // safe to use the function
}
Run Code Online (Sandbox Code Playgroud)

或更好(根据UpTheCreek赞成评论)

if (typeof me.onChange === "function") { 
    // safe to use the function
}
Run Code Online (Sandbox Code Playgroud)

  • ==='function'会比!='undefined'更好 (234认同)
  • @UpTheCreek,作为一般解决方案会有点危险,因为旧版本的IE将某些功能视为对象,例如`typeof window.alert ==='object'. (8认同)
  • @James,因为该语句实际上在JavaScript中抛出了一个`undefined`异常.我尝试过这个. (3认同)
  • @BornToCode因为那时`me.onChange`可以是评估为'true`的任何东西,不一定是函数(例如它可以是布尔值,字符串等).例如,请参阅http://jsfiddle.net/j5KAF/1/ (3认同)
  • 为什么不直接使用 `if (me.onChange) { // do something }` ? (2认同)
  • 只是为了指出明显的 `typeof me.onChange === "function"` 如果未定义全局 `me` 会失败。 (2认同)

Mis*_*dov 103

我有这个问题.

if (obj && typeof obj === 'function') { ... }
Run Code Online (Sandbox Code Playgroud)

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

最后我做了以下几点:

if (typeof obj !== 'undefined' && typeof obj === 'function') { ... }
Run Code Online (Sandbox Code Playgroud)

一位同事向我指出,检查是否存在!== 'undefined'然后=== 'function'当然是多余的.

更简单:

if (typeof obj === 'function') { ... }
Run Code Online (Sandbox Code Playgroud)

更清洁,工作得很好.

  • 为什么 typeof obj == 'function' 不够充分?;-) 提醒:严格相等测试运算符仅在静态操作数为空或 null 或 0 或受到任何此类强制转换时才有意义。 (2认同)

dav*_*wil 53

现代 JavaScript 来拯救你!

2021 年,这将在 JavaScript(和 TypeScript)中通过新的Optional Chaining语法解决* 。

me.onChange?.(str)
Run Code Online (Sandbox Code Playgroud)

如果onChange存在,它将被调用。

如果onChange不存在,则什么都不发生:表达式返回undefined

所以 for let value = me.onChange?.(str)value如果onChange不存在,将是未定义的。

请注意,如果onChange存在但不是函数,它会抛出 aTypeError就像您将任何非函数作为函数调用一样。Optional Chaining 并没有做任何神奇的事情来消除它。

* Optional Chaining 仍然是第 4 阶段的TC39 提案,所以技术上还没有包含在 ECMAScript 规范中。但是第 4 阶段意味着它基本上可以保证包含在下一个版本中。您现在可以通过 Babel 或 TypeScript 使用该语法,并确信它不会改变。

  • 关于使用此功能的警示故事:https://blog.jim-nielsen.com/2022/a-web-for-all/ (3认同)
  • 这是一个非常好的解决方案,我是一名中+ JS 开发人员,我不知道这一点,现在我将一直使用它 (2认同)
  • @duhaime `me` 未定义是一个单独的问题(该函数恰好位于问题中的 `me` 对象上) - 但是,如果您确实需要首先检查 `me` 是否已定义,您也可以这样做带有可选链接: `me?.onChange?.(str)` (2认同)

dhu*_*han 18

如果你使用eval将字符串转换为函数,并且想要检查这个eval'd方法是否存在,那么你需要在eval中使用typeof和你的函数字符串:

var functionString = "nonexsitantFunction"
eval("typeof " + functionString) // returns "undefined" or "function"
Run Code Online (Sandbox Code Playgroud)

不扭转这种和尝试的typeofEVAL.如果你做了一个ReferenceError将被抛出:

var functionString = "nonexsitantFunction"
typeof(eval(functionString)) // returns ReferenceError: [function] is not defined
Run Code Online (Sandbox Code Playgroud)

  • eval == evil;) (16认同)
  • 你可以不用eval做到这一点.示例:```var a ='alert'; window [a]('it works');``` (7认同)
  • 这可能是邪恶的,但是当函数名称在变量中时这非常有用。 (2认同)

Nas*_*ibi 12

怎么样:

if('functionName' in Obj){
    //code
}
Run Code Online (Sandbox Code Playgroud)

例如

var color1 = new String("green");
"length" in color1 // returns true
"indexOf" in color1 // returns true
"blablabla" in color1 // returns false
Run Code Online (Sandbox Code Playgroud)

或者就你的情况而言:

if('onChange' in me){
    //code
}
Run Code Online (Sandbox Code Playgroud)

请参阅MDN文档.

  • 这个线程的最佳解决方案,最短,最干净. (3认同)

Sam*_*vic 9

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

基本上,如果me.onChange未定义(如果它尚未启动它将会是这样),那么它将不会执行后一部分.如果me.onChange是一个函数,它将执行me.onChange(str).

你甚至可以走得更远:

me && me.onChange && me.onChange(str);
Run Code Online (Sandbox Code Playgroud)

如果我也是异步的.


Mat*_*son 8

尝试typeof- 寻找'undefined'说它不存在,'function'为一个功能.这个代码的JSFiddle

function thisishere() {
    return false;
}
alert("thisishere() is a " + typeof thisishere);
alert("thisisnthere() is " + typeof thisisnthere);
Run Code Online (Sandbox Code Playgroud)

或者作为if:

if (typeof thisishere === 'function') {
    // function exists
}
Run Code Online (Sandbox Code Playgroud)

或者使用返回值,在一行上:

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


Moh*_*tfi 7

function function_exists(function_name)
{
    return eval('typeof ' + function_name) === 'function';
}
alert(function_exists('test'));
alert(function_exists('function_exists'));
Run Code Online (Sandbox Code Playgroud)

或者

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';
}
Run Code Online (Sandbox Code Playgroud)


Mif*_*Fox 6

function js_to_as( str ){
     if (me && me.onChange)
         me.onChange(str);
}
Run Code Online (Sandbox Code Playgroud)


Muh*_*hir 6

//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");
    }
Run Code Online (Sandbox Code Playgroud)


Ayl*_*spa 6

这是一个有效且简单的解决方案,用于检查函数是否存在并由另一个函数动态触发该函数;

触发功能

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
    }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以使用 php 动态生成函数,如下所示

function runThis_func(my_Parameter){

    alert(my_Parameter +" triggerd");
}
Run Code Online (Sandbox Code Playgroud)

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

<?php

$name_frm_somware ="runThis_func";

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

?>
Run Code Online (Sandbox Code Playgroud)

您需要的确切 HTML 代码是

<input type="button" value="Button" onclick="runDynamicFunction('runThis_func');">
Run Code Online (Sandbox Code Playgroud)


Ale*_*lex 5

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

function js_to_as( str ){
     if (me && me.onChange && typeof me.onChange === 'function') {
         me.onChange(str);
     }
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*las 5

我喜欢使用这种方法:

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

用法:

if ( isFunction(me.onChange) ) {
    me.onChange(str); // call the function with params
}
Run Code Online (Sandbox Code Playgroud)


Pan*_*ood 5

Underscore.js 库在 isFunction 方法中将其定义如下(注释表明可能会迎合某些浏览器错误)

typeof obj == 'function' || false
Run Code Online (Sandbox Code Playgroud)

http://underscorejs.org/docs/underscore.html#section-143


小智 5

我遇到过这样的情况:函数的名称根据添加到函数名称的变量(在本例中为 var 'x')而变化。这有效:

if ( typeof window['afunction_'+x] === 'function' ) { window['afunction_'+x](); } 
Run Code Online (Sandbox Code Playgroud)


Luc*_*nte 5

如果您要检查 jQuery 插件的函数,则需要使用 $.fn.myfunction

if (typeof $.fn.mask === 'function') {
    $('.zip').mask('00000');
}
Run Code Online (Sandbox Code Playgroud)


Tu4*_*n3r 5

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

function func_exists(fname)
{
  return (typeof window[fname] === 'function');
}
Run Code Online (Sandbox Code Playgroud)


Lal*_*uak 5

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

function abc(){
}
!!window.abc; // return true
!!window.abcd; // return false
Run Code Online (Sandbox Code Playgroud)


Mat*_*osa 5

简而言之:捕获异常。

我真的很惊讶没有人在这篇文章中回答或评论 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;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)