【发布时间】:2009-10-11 14:11:53
【问题描述】:
假设我得到一个匿名函数,需要对其上下文进行操作,但它是绑定到“窗口”还是绑定到未知对象是不同的。
如何获得对调用匿名函数的对象的引用?
编辑,一些代码:
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 中挖掘并找到了一个 post 告诉使用“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:完整场景,如 cmets 中所述。
我正在使用 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 个函数的容器,并在循环中对它们进行全部测试,而不是手动编写这些东西。
【问题讨论】:
-
您能提供一些代码示例吗?我很难理解你真正想要什么。
-
是的,我不确定您在寻找什么。请提供一些代码示例。
-
请不要使用eval!请理解,这不是您作为 'bar' 函数的作者的问题。谁想要调用你的“bar”函数,必须传递一个“工作”回调函数。
-
另外,除了给出这个抽象的例子,你能告诉我们实际情况吗?
-
添加完整场景:-)
标签: javascript this anonymous-function