javascript - Can I make an invocable function from an object as the other way around? - Stack Overflow

Let's assume I have a function:var func = function(param){return param + 1;};Given that functions

Let's assume I have a function:

var func = function(param){return param + 1;};

Given that functions are objects, I can add properties to it:

func.prop = 'foo';

Both func(4) and func.prop should work. But now let's say that I have an object:

var obj = {prop: 'foo'};

...and I want to make it invocable as an increment function. Is this possible?

Let's assume I have a function:

var func = function(param){return param + 1;};

Given that functions are objects, I can add properties to it:

func.prop = 'foo';

Both func(4) and func.prop should work. But now let's say that I have an object:

var obj = {prop: 'foo'};

...and I want to make it invocable as an increment function. Is this possible?

Share Improve this question asked Nov 10, 2012 at 2:52 wwaawawwwaawaw 7,13710 gold badges35 silver badges42 bronze badges 5
  • 1 I asked a similar question not too long ago. See here. stackoverflow./questions/13227623/custom-function-class – SpaceFace Commented Nov 10, 2012 at 2:53
  • 3 ... "as an increment function" ... what? – Pointy Commented Nov 10, 2012 at 2:56
  • Blasted ment timer. Your idea seems simpler than mine. Is there any reason why you can't use a function with some cached properties for this? You can refer to the function using arguments.callee if you need to access it. I'm assuming you want this to work, even if you got an object to behave like a function this would still refer to window. Could you give us more information on what you're trying to do? Like this? jsfiddle/YhxDD – SpaceFace Commented Nov 10, 2012 at 3:01
  • @Pointy look at the question above... return param + 1 – wwaawaw Commented Nov 10, 2012 at 4:30
  • 1 OK I understand now; I just was somewhat confused as that is far from possible in JavaScript; you can't make an object act like a function unless it actually is a function, as explained in the good answer you got. – Pointy Commented Nov 10, 2012 at 13:53
Add a ment  | 

2 Answers 2

Reset to default 8

I want to make [an Object] invocable as an increment function. Is this possible?

No.

Objects created by the Object constructor do not have in internal [[Call]] method and therefore can't be called. It's the special [[Call]] method that makes a function a function. Note that the Object constructor is a Function, but it makes plain Objects, not functions.

While Functions inherit from Object.prototype, they are created by the Function constructor. Built–in constructors have extra powers given to them by ECMA-262. :-)

This is a bad idea (IMO, it's a lot of overhead for lame syntactic sugar), but it can be done.

function InvokableObject(properties) {
    var propName,
        invoke = properties.invoke,
        fn = typeof invoke === 'string' ? 
            function () {
                return fn[invoke].call(fn, arguments);
            } : 
            function () {
                return invoke.call(fn, arguments);
            };
    delete properties.invoke;
    for (propName in properties) {
        if (properties.hasOwnProperty(propName)) {
            fn[propName] = properties[propName];
        }
    }
    return fn;
}

Now, you can specify a function as the "invoke" property, and when you call the object, it will run:

var incrementable = InvokableObject({
    value: 0,
    invoke: function () {
        this.value += 1;
        return this.value;
    }
});

console.log(incrementable.value); //0
console.log(incrementable()); //1
console.log(incrementable()); //2

Alternately, you can specify the name of the invokation function:

var incrementable = InvokableObject({
    value: 0,
    invoke: 'increment',
    increment: function () {
        this.value += 1;
        return this.value;
    }
});

console.log(incrementable.value); //0
console.log(incrementable()); //1
console.log(incrementable()); //2

Seriously, though, don't do this. Just call obj.increment or whatever.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744168862a4561433.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信