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

时间:2009-06-25 04:10:54

标签: javascript

我跟着this guide创建了一个新的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);
}

但是,有时我的onChange无法加载。

的Firebug错误
  

me.onChange不是函数

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

有关如何确保其存在的任何建议,然后才执行onChange

(除了尝试捕捉一项工作外,以下所有方法都没有)

33 个答案:

答案 0 :(得分:1036)

尝试这样的事情:

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

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

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

答案 1 :(得分:96)

我有这个问题。

if (obj && typeof obj === 'function') { ... }
如果obj碰巧未定义,则

不断抛出引用错误。

最后我做了以下事情:

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

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

简单:

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

更干净,效果更好。

答案 2 :(得分:17)

如果您正在使用eval将字符串转换为函数,并且您想要检查此eval'd方法是否存在,那么您将需要在 typeof 和<强> EVAL

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

答案 3 :(得分:15)

抢救现代Javascript!

在2020年,将使用新的Optional Chaining语法在Java语言(以及Typescript)的语言级别上解决 *

me.onChange?.(str)

就这么简单-onChange 仅在存在的情况下被调用

如果onChange不存在,则什么也不会发生,并且表达式返回undefined。因此,如果返回本来应该使用的收益value,则可以在继续之前检查value !== undefined

一个边缘情况警告-如果存在onChange 但不是 一个函数,则得到TypeError。正如您所期望的那样,它与尝试将任何非函数作为函数调用相同,但是值得明确指出的是,“可选链接”并没有任何使它消失的魔力。

*好吧,从技术上讲,可选链接仍然只是第4阶段TC39 proposal,因此还不在ECMAScript规范中。但是第4阶段意味着已定稿,基本上可以保证将其包含在下一个版本中。您现在可以通过Babel或在Typescript中使用“可选链接”,并确信它不会改变。

答案 4 :(得分:9)

怎么样:

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

e.g。

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 docs

答案 5 :(得分:7)

尝试typeof - 查找'undefined'表示它不存在,'function'表示功能。 JSFiddle for this code

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

或者作为if:

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

答案 6 :(得分:7)

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

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

你甚至可以走得更远:

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

如果我也是异步的。

答案 7 :(得分:4)

我会更进一步,以确保该属性确实是一个功能

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

答案 8 :(得分:3)

对我来说最简单的方法:

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

答案 9 :(得分:3)

Underscore.js库在isFunction方法中定义它(这些评论建议可以解决一些浏览器错误)

 {  
  "success":true,
  "offer":{  
  "packageName":"com.myntra.android",
  "campKey":"284",
  "app_name":" Myntra",
  "image_url":"https:\/\/media.go2speed.org\/brand\/files\/wadogo\/142\/thumbnails_100\/unnamed-3.png",
  "desc1":"No Incent\r\nNo Free-Recharge apps traffic\r\nNO SMS\r\nNo Email\r\nNo Adult traffic\r\nNo Bot Traffic\r\nKPI - purchase% >10% of Total Installs. If not met, CPI payout will be pro-rata.\r\nNote: No social media traffic allowed. No traffic from Datalead.\r\n\r\nThe caps provided are network wide. \r\nPlease ask AM for individual Caps by Mail and Skype.\r\nexpiry date: TBA\r\nThe offer will stop converting once we hit the daily\/monthly cap\r\nCPI per install\r\nOnly use the creatives provided by us.\r\n\r\nPayout Slab:\r\n0-10 INR - Nill\r\n10-50 INR - $0.40\r\n50-100 INR - $0.62\r\n100-125 INR - $0.70\r\n125+ - $0.90",
  "desc2":null,
  "rdata":"[]",
  "cats":"0",
  "banner_url":"http:\/\/thegraphicsfairy.com\/wp-content\/uploads\/2014\/03\/Free-Banner-Frame-Image-2-GraphicsFairy.jpg",
  "click_url":"http:\/\/www.google.com",
  "country":"IN",
  "payout":0.12
  }
 }

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

答案 10 :(得分: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
}

答案 11 :(得分:3)

//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");
    }

答案 12 :(得分:2)

我总是这样检查:

if(!myFunction){return false;}

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

答案 13 :(得分:2)

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

将get_ID调用移动到onclick事件应该处理它。

显然你可以像前面提到的那样进一步陷阱:

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

答案 14 :(得分:2)

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

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

答案 15 :(得分:2)

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

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

答案 16 :(得分:2)

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

答案 17 :(得分:2)

我尝试过接受的答案;但是:

console.log(typeof me.onChange);

返回'undefined'。 我注意到规范声明了一个名为'onchange'而不是'onChange'的事件(请注意camelCase)。

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

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

答案 18 :(得分: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);
}

答案 19 :(得分:1)

简而言之:捕获异常。

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

详细信息:下面的功能是我的代码库中的一个示例。当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;
    }
  }

}

答案 20 :(得分:1)

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

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

答案 21 :(得分:1)

如果你正在检查一个jQuery插件的函数,你需要使用$ .fn.myfunction

if (typeof $.fn.mask === 'function') {
    $('.zip').mask('00000');
}

答案 22 :(得分: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
*/

答案 23 :(得分: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;
}

答案 24 :(得分:0)

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

OR

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';
}

答案 25 :(得分:0)

这是一个工作且简单的解决方案,用于检查存在功能由另一个功能动态分类该功能;

触发功能

function runDynmicFunction(functionname){ 

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

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

现在您可以动态生成函数,也许可以使用像这样的

function runThis_func(my_Parameter){

    alert(my_Parameter +" triggerd");
}

现在您可以使用动态生成的事件

来调用该函数
<?php

$name_frm_somware ="runThis_func";

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

?>

您需要的确切HTML代码是

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

答案 26 :(得分:0)

然后有这个......

( document.exitPointerLock || Function )();

答案 27 :(得分:0)

// just pass your tested function name instead of myFunctionName
if ( $.isFunction($.fn.myFunctionName) ) {
    console.log( 'write your code here.' );
}

答案 28 :(得分:0)

这将验证函数是否存在,如果存在,将执行

StringBuilder builder = new StringBuilder();
for(int i = 0; i <= clientListpost.length -1; i++){
  if(clientpost[i]) { //or clientpost[i] == true

    //if there's already something in the String, add a comma first
    if(builder.length() > 0) { 
      builder.append(",");
    } 

    //add the element
    builder.append(client[i]);
  } 
}
clientUrl += builder.toString(); //assumes there's more in clientUrl, otherwise just assign

因此错误me.onChange && me.onChange(str); 是可以防止的。

答案 29 :(得分: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*/
    }

答案 30 :(得分:0)

我建议使用:

function hasMethod(subject, methodName) {
  return subject != null && typeof subject[methodName] == "function";
}

第一张支票subject != null过滤掉没有任何属性的空值(nullundefined)。如果没有此项检查,subject[methodName]可能会引发错误:

TypeError :(未定义|空)没有属性

仅检查真实值是不够的,因为0""都是伪造的,但确实具有属性。

在确认subject不为空之后,您可以安全地访问属性并检查其是否与typeof subject[methodName] == "function"相匹配。


将此应用于您的代码,您现在可以执行以下操作:

if (hasMethod(me, "onChange")) {
  me.onChange(str);
}

答案 31 :(得分:0)

function isFunction(o){返回null!== o &&“ function” === type of o && !! o.apply; }

答案 32 :(得分:-1)

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

header { width: 100%; z-index: 3; display: flex; align-items: center; justify-content: right; background-color: #68c7c1; min-height: 56px; transition: min-height 0.3s; } header #menu { margin-left: auto; margin-right:10px; color: #eceeef; font-size: 2em; } .nav { width: 100%; height: auto; z-index: 2; display: flex; flex-wrap: wrap; background-color: #68c7c1; } .nav-sm, .nav-lg { display: none; } .nav-sm.open { display: flex; flex-wrap: wrap; align-items: center; height: calc(100% - 56px); margin-top: -2px; } .nav__list, .nav__item { width: 100%; } .nav__list { display: flex; flex-wrap: wrap; } .nav__item { height:50px; display: flex; flex-wrap: nowrap; justify-content: center; } .nav__item a { text-decoration: none; text-align: center; font-size: 1.2em; color: #eceeef; } .nav-sm.open { -webkit-animation: slide-down .3s linear; -moz-animation: slide-down .3s linear; } .nav-sm.open .nav__item{ padding-bottom: 80px; font-size: 2em; } .nav-sm.open .nav__item:nth-child(1) { -webkit-animation: slide-down .3s .1s linear; -moz-animation: slide-down .3s .1s linear; } .nav-sm.open .nav__item:nth-child(2) { -webkit-animation: slide-down .3s .2s linear; -moz-animation: slide-down .3s .2s linear; } .nav-sm.open .nav__item:nth-child(3) { -webkit-animation: slide-down .3s .3s linear; -moz-animation: slide-down .3s .3s linear; } @-webkit-keyframes slide-down { 0% { opacity: 0; -webkit-transform: translateY(-100%); } 100% { opacity: 1; -webkit-transform: translateY(0%); } } @-moz-keyframes slide-down { 0% { opacity: 0; -moz-transform: translateY(-100%); } 100% { opacity: 1; -moz-transform: translateY(0%); } } ;