JavaScriptの関数が定義されているかどうかはどのようにわかりますか?
このようなことをしたい
function something_cool(text, callback) {
alert(text);
if( callback != null ) callback();
}
しかし、それは私を取得します
コールバックは関数ではありません
コールバックが定義されていない場合のエラー。
typeof callback === "function"
現在の回答はすべてリテラル文字列を使用していますが、可能な場合はコードに含めない方がよいでしょう-これはそうではありません(そして、起動するために価値のある意味を提供します):
function isFunction(possibleFunction) {
return typeof(possibleFunction) === typeof(Function);
}
個人的には、コードにぶら下がる文字列の数を減らすようにしています...
また、typeof
は演算子であり、関数ではないことを認識していますが、後者として表示される構文を使用してもほとんど害はありません。
if (callback && typeof(callback) == "function")
コールバックは、false
、undefined
、0
、またはnull
の場合、(それ自体で)false
に評価されることに注意してください。 null
との比較は非常に具体的です。
変数が定義されていない場合、関数が実装されているかどうかを判断するメソッドも失敗するため、文字列の受信をサポートするより強力なものを使用しています。
function isFunctionDefined(functionName) {
if(eval("typeof(" + functionName + ") == typeof(Function)")) {
return true;
}
}
if (isFunctionDefined('myFunction')) {
myFunction(foo);
}
JavaScriptを初めて使用した場合、動作が変更されたかどうかはわかりませんが、Jason Bunting(6年前)によって提供されたソリューションは、possibleFunctionが定義されていないと機能しません。
function isFunction(possibleFunction) {
return (typeof(possibleFunction) == typeof(Function));
}
エンジンがシンボルpossibleFunctionを解決しようとすると、これはReferenceError: possibleFunction is not defined
エラーをスローします(Jasonの答えへのコメントで述べたように)
この動作を回避するには、存在するかどうかを確認する関数の名前のみを渡すことができます。そう
var possibleFunction = possibleFunction || {};
if (!isFunction(possibleFunction)) return false;
これにより、変数がチェックする関数または定義されていない場合は空のオブジェクトに設定され、上記の問題が回避されます。
試してください:
if (typeof(callback) == 'function')
するかもしれない
try{
callback();
}catch(e){};
受け入れられた答えがあることは知っていますが、誰もこれを提案しませんでした。これがイディオムの説明に当てはまるかどうかはわかりませんが、すべての場合に有効です。
新しいJavaScriptエンジンでは、代わりにfinally
を使用できます。
if ('function' === typeof callback) ...
function something_cool(text, callback){
alert(text);
if(typeof(callback)=='function'){
callback();
};
}
これを試して:
callback instanceof Function
試してください:
if (!(typeof(callback)=='undefined')) {...}
言及されているライブラリ@Venkat Sudheer Reddy Aedamaの source underscorejsを見ると、これを見ることができます。
_.isFunction = function(obj) {
return typeof obj == 'function' || false;
};
これはちょうど私のヒントです、ヒントの答え:>
http://underscorejs.org を使用すると、次のようになります。 http://underscorejs.org/#isFunction
_.isFunction(callback);
JQuery関数が定義されているかどうかを確認する方法を探していましたが、簡単に見つかりませんでした。
おそらくそれが必要かもしれません;)
if(typeof jQuery.fn.datepicker !== "undefined")
関数を再定義する場合は、関数はどこで発生してもグローバルに定義されるため、関数変数は発生順に定義されるのが最適です。
同じ名前の以前の関数を呼び出す新しい関数を作成する例:
A=function() {...} // first definition
...
if (typeof A==='function')
oldA=A;
A=function() {...oldA()...} // new definition
グローバル関数の場合、回答の1つで提案されているeval
の代わりにこれを使用できます。
var global = (function (){
return this;
})();
if (typeof(global.f) != "function")
global.f = function f1_shim (){
// commonly used by polyfill libs
};
global.f instanceof Function
も使用できますが、わかりません。 Function
の値はフレームごとに異なるため、単一フレームアプリケーションでのみ適切に機能します。そのため、通常は代わりにtypeof
を使用します。環境によっては、typeof f
にも異常がある場合があることに注意してください。 MSIE 6-8では、たとえばalert
などの一部の関数には「オブジェクト」タイプがありました。
ローカル関数によって、受け入れられた回答にあるものを使用できます。関数がローカルかグローバルかをテストすることもできます。
if (typeof(f) == "function")
if (global.f === f)
console.log("f is a global function");
else
console.log("f is a local function");
質問に答えるために、サンプルコードは最新のブラウザでエラーなく動作しているので、何が問題なのかわかりません。
function something_cool(text, callback) {
alert(text);
if( callback != null ) callback();
}
注:callback !== undefined
の代わりにcallback != null
を使用しますが、ほとんど同じです。
すべてではないにしても、ほとんどの以前の回答には、関数を呼び出す副作用があります
ここでベストプラクティス
あなたには機能があります
function myFunction() {
var x=1;
}
//direct way
if( (typeof window.myFunction)=='function')
alert('myFunction is function')
else
alert('myFunction is not defined');
//byString
var strFunctionName='myFunction'
if( (typeof window[strFunctionName])=='function')
alert(s+' is function');
else
alert(s+' is not defined');
関数で一度だけではなくcallback()
を呼び出す場合、再利用のために引数を初期化できます。
callback = (typeof callback === "function") ? callback : function(){};
例えば:
function something_cool(text, callback) {
// Initialize arguments
callback = (typeof callback === "function") ? callback : function(){};
alert(text);
if (text==='waitAnotherAJAX') {
anotherAJAX(callback);
} else {
callback();
}
}
制限は、定義されていなくても常にコールバック引数を実行することです。