javascript curry/partial function invokation for object functions
I want a 'curry' like funct开发者_开发知识库ion - this kind of thing
function invoker (fn) {
var slice = Array.prototype.slice,
args = slice.apply(arguments, [1]);
return function () {
return fn.apply(null, args);
};
}
But I want the user to be able to do
invoker(f)
or
invoker(foo.bar)
I cant find the correct magic incantation to do this. All the examples I see require the scope object to be passed in separately; which is error prone and not natural. IE
invokerx(foo.bar, foo)
IS there anyway to do this? I dont mind having 2 different functions
invokeG(f)
invokeO(foo.bar)
EDIT : clarification
'f' is a global scope function
'foo' is an object
'bar is a method on that object
IE I want this curry tool to work with'free' functions as well as with object functions.
Having to go
<curry function>(foo.bar,foo)
seems kinda clunky, I have have to say 'foo' twice
The first argument of apply
is the this
that is available to the function. Since you're passing null
, this
will get mapped to window
.
The following modification will work:
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 Added a slight change to add support for name passing so you don't have to pass the object name twice.
UPDATE 2 Since we're currying, we need there to always be two arguments.
You can't. When you do invoker(foo.bar)
, invoker
has no way of knowing that the argument is a member function of foo
. Functions do not store their "owner", and invoker
is just passed a reference to a function.
The closest you can get is to use function.bind()
, like this:
invoker(foo.bar.bind(foo))
精彩评论