匿名関数がそのコンテキストに基づいて動作する必要があるとしましょう。ただし、それが「ウィンドウ」にバインドされているか、不明なオブジェクトにバインドされているかは異なります。
匿名関数が呼び出されたオブジェクトへの参照を取得するにはどうすればよいですか?
編集、いくつかのコード:
var ObjectFromOtherLibIAmNotSupposedToknowAbout = {
foo : function() {
// do something on "this"
}
}
var function bar(callback) {
// here I want to get a reference to
// ObjectFromOtherLibIAmNotSupposedToknowAbout
// if ObjectFromOtherLibIAmNotSupposedToknowAbout.foo is passed
// as callback
}
bar(ObjectFromOtherLibIAmNotSupposedToknowAbout.foo);
あなたは合法的に尋ねるかもしれません、なぜあなたはそのようなことをしたいのですか?さて、私は最初に配列として渡された引数を解凍したかったのです。*
Pythonの" "演算子と同じように:
>>> args = [1,2,3]
>>> def foo(a,b,c) :
print a,b,c
>>> foo(*args)
1 2 3
SOを掘り下げて、「apply()」を使用するように指示する投稿を見つけました。
function bar(callback, args){
this[callback].apply(this, args);
}
オブジェクト内の場合は現在の「this」を使用し、そうでない場合は「window」を使用するため、興味深いものです。
しかし、私は問題があると思います:
「bar()」自体がオブジェクト内にある場合、「this」は「bar()」コンテナを参照するため、動作しません。
ところで、スコープをパラメーターとして渡さないようにしたいと思います。
もちろん、引数と関数を文字列として連結してevalを使用することもできますが、これは、よりクリーンなものが見つからない場合にのみ使用したいと思います。
もちろん、それが不可能な場合(結局のところ、それは可能性があります)、私はします:
function foo(func, args)
{
eval("func("+args.join(", ")+");");
}
編集2:コメントで尋ねられた完全なシナリオ。
私はqunitを使用してJavascriptでユニットテストを実行しています。かっこいいですが、何かが例外を発生させるかどうかを確認する方法がありません。
最も基本的なテストはそのように行われます:
/**
* Asserts true.
* @example ok( $("a").size() > 5, "There must be at least 5 anchors" );
*/
function ok(a, msg) {
_config.Test.push( [ !!a, msg ] );
}
アイデアは次のようなものを作ることです:
jqUnit.prototype.error = function(func, args, msg)
{
try
{
eval("func("+args.join(", ")+");");
config.Test.push( [ false, msg + " expected : this call should have raised an Exception" ] );
} catch(ex)
{
_config.Test.push( [ true, msg ] );
}
};
私がevalを取り除くことができれば、それは素晴らしいことです。そして、なぜスコープをパラメーターとして使用したくないのですか?手作業で作成するのではなく、スコープの異なる20個の関数を参照するコンテナーをループして、それらすべてをループ内でテストしたい場合があるためです。