2016-11-02 16 views
1

私は自分の関数の1つでコールバックを作る必要がありますが、プログラム全体が動作しているので、関数自体ではなく文字列の形でコールバック関数名を渡す必要があります。例えばJavascript:eval()を使用せずに文字列をコールバックとして使用する方法はありますか?

:要するに

function doThings(callback){ 
    alert('hello'); 
    eval(callback + '();'); 
} 

function test(){ 
    alert('world!'); 
} 

var func = 'test'; 

doThings(func); 

、私は動的に使用される機能変更しようとしている、と私は、コールバック関数ではなく、実際の関数の参照を表す文字列を使用しなければなりません。

私はevalが悪であることを覚えています - eval()なしでこれを行う方法はありますか?

EDIT:オブジェクトの関数をあらかじめリストアウトする機能はありません。私はまた、この関数に個別の引数として配列を渡す必要があります。何らかの理由で.apply()がうまくいっていません。window[callback]()

+0

どの環境あなたはしていますか?ブラウザでは、doThings(window [func])、window ['test']()などがあり、親スコープオブジェクトから名前で関数にアクセスできます。 – DevDig

+0

@DevDigブラウザーにあります。私はそれを試みたが、ウィンドウ[func]()。apply(null、args)を実行しても機能しません。私は先にそれを言及すべきだった。関数に個別の引数として配列を渡す必要もあります。 これで、すべての変数を英数字に制限している場合、eval()を使用することは必ずしも安全ではないですか?これは、SQLを生成し、入力をサニタイズするよりも、どのように安全性が低くなりますか? – geekman

+0

ウィンドウ[func]()は、ウィンドウ[func] .apply(null、args)と同様にトリックを行う必要があります。悪い評価に関するいくつかの情報:https://javascriptweblog.wordpress.com/2010/04/19/how-evil-is-eval/ – DevDig

答えて

5

オブジェクトを関数に格納します。プロパティ名を使用してアクセスします。

function doThings(callback) { 
 
    alert('hello'); 
 
    my_possible_functions[callback](); 
 
} 
 

 
function test() { 
 
    alert('world!'); 
 
} 
 

 
var my_possible_functions = {}; 
 
my_possible_functions.test = test; 
 

 

 
var func = 'test'; 
 
doThings(func);

+0

私の現在の状況では、すべての機能を一覧表示する能力がありませんそのようなオブジェクトは残念です。 – geekman

+0

@Archer私たちはアイデアをupvotedと思います。はい、タイプミスがありましたが、私はIdeaがもっと重要だと思います。 – Rajesh

+0

@Rajeshそれでは、とにかく修正されていますので、それはすべて役に立ちます:) – Archer

0

@Quentinさんが、追加チェック

  • チェックと非常によく似答えその場合、現在のObjectの一部値はタイプfunctionであれば
  • チェック。値が関数でない場合は、コードが壊れてしまいます。

function doThings(callback) { 
 
    console.log('hello ', callback); 
 
    try { 
 
    callbackList[callback]() 
 
    } catch (ex) { 
 
    console.log(ex.message) 
 
    } 
 
    
 
    callbackList.hasOwnProperty(callback) && typeof(callbackList[callback]) === 'function' && callbackList[callback]() 
 
} 
 

 
Object.prototype.test3 = function() { 
 
    console.log("this should not be called"); 
 
} 
 

 
var callbackList = { 
 
    test: function test() { 
 
    console.log('world!'); 
 
    }, 
 
    test2: "World" 
 
} 
 

 
doThings('test'); 
 
doThings("test2"); 
 
doThings("test3");

+0

私は能力がありません私の状況では、オブジェクトをコールバックでいっぱいにする。 – geekman

1

あなたはこの方法で、これを行うことができます。

function doThings(callback){ 
 
    alert('hello'); 
 
    window[callback](); 
 
} 
 

 
function test(){ 
 
    alert('world!'); 
 
} 
 

 
var func = 'test'; 
 

 
doThings(func);

それとも文字列で、フル機能を渡し、Functionコンストラクタを使用することができます。

function doThings(callback){ 
 
    alert('hello'); 
 
    (new Function('return '+callback)())(); 
 
} 
 

 
function test(){ 
 
    alert('world!'); 
 
} 
 

 
var func = test.toString(); 
 

 
doThings(func);

+0

更新されました。以前のテストで、削除するのを忘れました;) –

+0

全く同じソリューションを投稿しようとしていました。しかし、コールバック関数がこれを動作させるためにグローバルスコープを持つ必要があることは、おそらく重要ではないにしても言及する価値があります。 – Archer

+0

私は最初のものを試しましたが、私のコードでapply()を使う必要があったので、個々の引数としてコールバックに配列を渡すことができました。 私は2番目のものが好きです。私はそれを試みると思う。ありがとう! – geekman

関連する問題