我可以从对象中创建一个可调用的函数吗?

时间:2012-11-10 02:52:11

标签: javascript function object

我们假设我有一个功能:

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

鉴于函数是对象,我可以为其添加属性:

func.prop = 'foo';

func(4)func.prop都应该有用。但现在让我们说我有一个对象:

var obj = {prop: 'foo'};

...我希望将其作为增量函数调用。这可能吗?

2 个答案:

答案 0 :(得分:5)

  

我想将[Ojbect]作为增量函数进行调用。这可能吗?

没有。

Object构造函数创建的对象没有内部[[Call]]方法,因此无法调用。这是使函数成为函数的特殊[[Call]]方法。请注意,Object构造函数是一个Function,但它生成普通的Object,而不是函数。

虽然函数继承自Object.prototype,但它们是created by the Function constructor。内置构造函数具有ECMA-262赋予它们的额外功能。 : - )

答案 1 :(得分:1)

这是一个坏主意(IMO,它是蹩脚的语法糖的很多开销),但它可以做到。

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;
}

现在,您可以将一个函数指定为“invoke”属性,当您调用该对象时,它将运行:

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

或者,您可以指定invokation函数的名称:

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

但是,说真的,不要这样做。只需调用obj.increment或其他任何内容。