[英]How to get the “this” (scope) of a Javascript anonymous function?
假設我得到一個匿名函數需要對其上下文進行操作,但它是否與“窗口”或未知對象綁定是不同的。
如何從對象中引用匿名函數?
編輯,一些代碼:
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個函數的容器,並在循環中測試它們而不是手動編寫內容。
E-SATIS,
唯一的方法是使用call或apply方法來設置正確的“上下文”。
要解決您的問題,請修改條形函數以接受回調函數以及應用於該回調函數的范圍。
function bar(callback, scope)
{
callback.apply(scope);
}
bar(ObjectFromOtherLibIAmNotSupposedToknowAbout.foo, ObjectFromOtherLibIAmNotSupposedToknowAbout);
或者,您可以使用“綁定”方法。
Function.prototype.bind = function(context) {
var fun = this;
return function(){
return fun.apply(context, arguments);
};
};
現在,您可以保持條形函數不變,並修改調用代碼,看起來像,
bar(ObjectFromOtherLibIAmNotSupposedToknowAbout.foo.bind(ObjectFromOtherLibIAmNotSupposedToknowAbout));
編輯:
正如我在評論中指出的那樣,調用代碼負責傳遞正確的回調函數。 您的“條形”功能無法確定使用的范圍,句點。
以此為例,
var LibObject = { foo: function() { //use this inside method } };
var fooFunction = LibOjbect.foo;
bar(fooFunction);
你怎么弄清楚范圍應該是什么? 現在沒有任何東西可以“解析”,你無法修改你的“條形”功能來完成這項工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.