开发者

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))
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜