web-dev-qa-db-ja.com

変数で指定されたJavaScript関数を呼び出す

JavaScript関数の名前を含むJavaScript変数があります。この関数は、$。ajaxなどを使用してロードおよび配置されることでページに存在します。

変数で指定されたjavascript関数を呼び出す方法を教えていただけますか?

(現在のページに挿入される)ページフラグメントの読み込みに使用されるURLには、呼び出す関数の名前が含まれているため、関数の名前は変数に含まれています。

このソリューションを実装する方法に関する他の提案を受け入れています。

140
Matt W

評価は避けたい。

この問題を解決するには、JavaScriptに関するこれらのことを知っておく必要があります。

  1. 関数はファーストクラスのオブジェクトであるため、オブジェクトのプロパティ(この場合、methodsと呼ばれる)または配列の要素になります。
  2. 関数が属するオブジェクトを選択しない場合、グローバルスコープに属します。ブラウザでは、グローバルが存在する「window」という名前のオブジェクトにぶら下がっていることを意味します。
  3. 配列とオブジェクトは密接に関連しています。 (噂は近親相姦の結果かもしれません!)角括弧.の代わりにドット[]を使用するか、またはその逆を使用することができます。

あなたの問題は、角括弧ではなく点の参照方法を検討した結果です。

だから、なぜそうではないのですか、

window["functionName"]();

それはあなたの機能がグローバル空間に住んでいると仮定しています。名前空間を付けた場合:

myNameSpace["functionName"]();

Evalを避け、setTimeoutおよびsetIntervalに文字列を渡さないでください。私はたくさんのJSを書いていますが、evalは必要ありません。 「必要」評価は、言語を十分に知らないことから生じます。スコープ、コンテキスト、および構文について学習する必要があります。あなたがこれまでに評価で立ち往生している場合は、尋ねるだけです-あなたはすぐに学びます。

241
Nosredna

グローバルスコープにある場合は、以下を使用することをお勧めします。

function foo()
{
    alert('foo');
}

var a = 'foo';
window[a]();

eval()より。 eval()evaaaaaal であるためです。

Nosrednaが40秒前に言ったように、それは>。<

61
anddoutoi

evalを使用してこのようなことを絶対に避けてください。そうしないと、XSS(クロスサイトスクリプティング)の脆弱性にさらされることになります。

たとえば、ここで提案されているevalソリューションを使用する場合、悪意のあるユーザーは次のようなリンクを被害者に送信できます。

http://yoursite.com/foo.html?func=function() {alert( 'Im%20In%20Teh%20Codez');}

そして、あなたのものではなくjavascriptが実行されます。このコードは、もちろん警告を表示するだけでなく、はるかに悪いことをする可能性があります。 Cookieを盗んだり、アプリケーションにリクエストを送信したりする可能性があります。

そのため、ユーザー入力(およびユーザー入力と見なされるクエリ文字列ID上のもの)から来るeval信頼できないコードは絶対に使用しないでください。ユーザー入力を関数を指すキーとして使用できますが、指定された文字列がオブジェクトのキーと一致しない場合は何も実行しないでください。例えば:

// set up the possible functions:
var myFuncs = {
  func1: function () { alert('Function 1'); },
  func2: function () { alert('Function 2'); },
  func3: function () { alert('Function 3'); },
  func4: function () { alert('Function 4'); },
  func5: function () { alert('Function 5'); }
};
// execute the one specified in the 'funcToRun' variable:
myFuncs[funcToRun]();

funcToRun変数がmyFuncsオブジェクト内の何もポイントしていない場合、これは失敗しますが、コードは実行されません。

22
pkaeding

これはちょっといですが、それが私の頭に浮かんだ最初のものです。これにより、引数を渡すこともできます。

eval('var myfunc = ' + variable);  myfunc(args, ...);

引数を渡す必要がない場合、これはもっと簡単かもしれません。

eval(variable + '();');

標準のドライコード警告が適用されます。

4
Bryan McLemore