我想要一个'咖喱'之类的功能 - 这种事情
function invoker (fn) {
var slice = Array.prototype.slice,
args = slice.apply(arguments, [1]);
return function () {
return fn.apply(null, args);
};
}
但我希望用户能够做到
invoker(f)
或
invoker(foo.bar)
我无法找到正确的魔法咒语来做到这一点。我看到的所有示例都要求范围对象单独传递;这容易出错并且不自然。 IE
invokerx(foo.bar, foo)
到底有没有这样做?我不介意有两个不同的功能
invokeG(f)
invokeO(foo.bar)
编辑:澄清
'f' is a global scope function
'foo' is an object
'bar is a method on that object
IE我希望这个咖喱工具能够使用“自由”功能以及对象功能。
必须去
<curry function>(foo.bar,foo)
看起来有点笨重,我不得不说'foo'两次
答案 0 :(得分:4)
apply
的第一个参数是函数可用的this
。由于您传递了null
,this
将被映射到window
。
以下修改将起作用:
function invoker (fn, target) {
var slice = Array.prototype.slice,
args = slice.apply(arguments, [2]);
if(typeof fn === 'string')
fn = (target || window)[fn];
return function () {
return fn.apply(target || null, args);
};
}
// Either will work:
invoker(foo.bar, foo);
invoker('bar', foo);
// Any of these will work:
invoker(escape, null);
invoker(escape, window);
invoker('escape', null);
invoker('escape', window);
UPDATE 添加了一些细微的更改,以添加对名称传递的支持,因此您不必两次传递对象名称。
更新2 由于我们正在讨论,我们需要总是有两个参数。
答案 1 :(得分:2)
你做不到。执行invoker(foo.bar)
时,invoker
无法知道参数是foo
的成员函数。函数不存储它们的“所有者”,invoker
只传递对函数的引用。
最接近的是使用function.bind()
,如下所示:
invoker(foo.bar.bind(foo))