[英]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.