JavaScriptに関数が存在するかどうかを確認するにはどうすればよいですか?


534

私のコードは

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か?

(1つの作業をキャッチする以外の方法はありません)


1
@SteveChambersやったよ 思い出させていただきありがとうございます。
Alec Smart


例外をキャッチします。私の答えをチェックしてください
Matteus Barbosa

回答:


1226

次のようなものを試してください:

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

またはそれ以上(UpTheCreekの賛成投票による)

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

249
=== 'function'は!= 'undefined'より優れています
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
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 ReferenceError developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
ミーシャNasledov

これは私にとっては
うまくいく

1
typeof obj == 'function'では不十分な理由は何ですか?;-)注意:厳密な等価テスト演算子は、静的なオペランドが空またはnullまたは0であるか、このようなキャストアマルゲームの対象である場合にのみ意味があります。
Fabien Haddadi

16

文字列を関数に変換するためにevalを使用していて、このevalされたメソッドが存在するかどうかを確認する場合は、eval内でtypeofと関数文字列を使用する必要があります。

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

これを元に戻してtypeofevalで試さないでください。ReferenceErrorがスローされる場合:

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

21
eval == evil;)
イエティ

1
悪いかもしれませんが、これは関数名が変数に含まれている場合に非常に役立ちます。
Luke Cousins、

8
evalなしでこれを行うことができます。例:var a = 'alert'; window[a]('it works');
zennin 2017年

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 docsを参照してください。


私はそれがあるかを知りたい場合は、この解決策は、例えば毎回:(機能していない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
}

または、戻り値を使用して、1行で:

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

&&テイクの左側の条件は、jQueryのisFunction右側のjQuery が処理&&しないものを処理しますか?
SantiBailors 2017年

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; }が、マイナーな調整です
Mr Heelis

4

プロパティが実際に関数であることを確認するために、さらに1ステップ進みます。

function js_to_as( str ){
     if (me && me.onChange && typeof me.onChange === 'function') {
         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 2018

2つのケースでは、存在を確認する関数パラメーターの名前を指定してfunction_existsを呼び出すだけで、boolが返されます。
Mohammad Lotfi 2018年


3

一言で言えば、例外をキャッチします。

この投稿で例外キャッチについて誰も答えたりコメントしたりしていないことに本当に驚いています。

詳細:ここでは、マスクフィールドのプレフィックスとフォームフィールド「名前」のサフィックスが付いた関数を照合する例を示します。JavaScriptが関数を見つけられない場合は、catchセクションで希望どおりに処理できるReferenceErrorをスローする必要があります。

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オンロードが正しく割り当てられていないのはないとます。

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

私は受け入れられた答えを試しました。しかしながら:

console.log(typeof me.onChange);

「未定義」を返します。仕様に「onChange」ではなく「onchange」というイベントが記述されていることに気付きました(キャメルケースに注意してください)。

元の受け入れられた回答を次のように変更するとうまくいきました:

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

2

jQueryプラグインである関数をチェックする場合は、$。fn.myfunctionを使用する必要があります

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

2

私はこの問題のエレガントな解決策も探していました。よく考えた結果、私はこのアプローチが一番良いと思いました。

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


あなたがminimalizmに行くつもりなら、これを行うこともできます:(me.onChange||(_=>_))()関数が存在する場合はそれを実行し、そうでなければ何もしません。
JSideris

良いですme.onChange && me.onChange()、ボイド関数を定義防ぐために。
necrifede

2

救助のための最新のJavascript!

これは長い回答リストで見られる可能性が低いかもしれませんが、新しいオプションのチェーン構文により言語レベルで解決されました*。

me.onChange?.(str)

それはそれと同じくらい簡単です- onChange存在する場合にのみ呼び出されます

場合はonChange何も起こらない、存在し、そして発現戻っていないundefined-それはあなたがそうでなければ使用したいという戻り値を持っている場合、あなたは、単にこの値を確認することができます!== undefined続行する前に。

エッジケースの警告- 存在しても機能しない場合onChange 、を取得します。これは、ご想像のとおり、非関数を関数として呼び出そうとするのと同じですが、オプションの連鎖は、これをなくすための魔法を使わないことを明示的に指摘する価値があります。TypeError

*さて、技術的に言えば、オプションチェーンはまだステージ4 TC39提案であるため、まだ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'は、さまざまな理由から、他のラッパーをtry-catchするようなものであるため、時間の遅延が生じます。「スロー」する可能性のあるevalの代替手段もあります。「新しいFunction(parms、body)」はおそらくエラーをスローするだろうと思いますが、私にとっての次の質問は速度の比較であり、それ以外の場合は最良のコードサイズの削減です(私にとってはより高速です)。[うーん、これは新しく見えます。私はそれを試していませんjsben.ch]
マスタージェームズ

代わりに新しい関数を呼び出すことについてのmmm rlyの興味深い点。私の回答に対する変更提案を自由に提出してください。
たくさん

はい、bashでも「source myScript.sh」を使用すると、エイリアスなどを介して「エクスポート」できるようになります。クラスやライブラリは、常にすべてのコードに固有のプロパティであるようです。確実に認可されていない場合は、jsインタープリターのチェックコードが必要です。コードの最も単純な公理的性質を理解するのに役立つもう1つの楽しい課題である1つの関数で1つを作成しました。実行時でさえ、誰の能力も超えていません。
マスタージェームズ

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
*/


0
// just pass your tested function name instead of myFunctionName
if ( $.isFunction($.fn.myFunctionName) ) {
    console.log( 'write your code here.' );
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.