你能让一个对象“可调用”吗?

IT技术 javascript
2021-03-04 09:12:14

是否可以通过实现callapply对象上或以其他方式使对象可调用例如:

var obj = {};
obj.call = function (context, arg1, arg2, ...) {
    ...
};

...

obj (a, b);
4个回答

不,但您可以向函数添加属性,例如

function foo(){}
foo.myProperty = "whatever";

编辑:要“制作”一个可调用的对象,您仍然必须执行上述操作,但它可能看起来像:

// Augments func with object's properties
function makeCallable(object, func){
    for(var prop in object){
        if(object.hasOwnProperty(prop)){
            func[prop] = object[prop];
        }
    }
}

然后你只需使用“func”函数而不是对象。实际上,此方法所做的只是在两个对象之间复制属性,但是……它可能对您有所帮助。

我希望有一个符号可以设置为使对象可调用,例如 obj[Symbol.invoke] = function(args) { };
2021-04-27 09:12:14
@NickSotiros 也许Object.setPrototypeOf(func, object)
2021-05-01 09:12:14
仅供参考:在 NodeJS 中,如果属性名称与函数对象上的只读属性(例如name. 例子:(function(){}).name=''; TypeError: Cannot assign to read only property 'name' of function 'function(){}'
2021-05-02 09:12:14
@NickSotiros 要使对象“可调用”,您可以从对象的构造函数中返回 aProxy
2021-05-12 09:12:14
是的,但你如何复制原型链?我需要一个可调用的函数/对象,但实际上是一个类型的实例。
2021-05-19 09:12:14

ES6现在有更好的解决方案。如果您以不同的方式创建您的对象(使用class, extending 'Function' 类型),您可以拥有它的一个可调用实例。

另请参阅:如何使用 ES6 类扩展函数?

extends每个“类”都有一个,所以您宁愿使用它来解决语言问题,重用您可能应该在类中聚合的代码,或者应该仅将它用于域对象中的自然连接?
2021-04-29 09:12:14
@wandalen 恐怕我不明白你想说什么。无论如何,一个更易读、更清晰和(实际上是)直观的(至少对于那些来自 c++ 或 java - OOP 的人)解决方案更好,不是吗?为什么您认为扩展“功能”以创建可调用的类不直观?
2021-05-13 09:12:14
如果您还提供了代码片段,那就太好了。
2021-05-14 09:12:14
我不会称它为更好。主流浏览器更好地支持该解决方案,这实际上迫使人们使用该解决方案而不是替代方案。但它根本没有使这个解决方案更好。此解决方案违反直觉,并且与其他 OOP 方法不兼容。
2021-05-16 09:12:14

遵循@Max 的同一行,但使用 ES6 扩展将Object对象的所有属性和原型传递obj给 callable func

Object.assign(func, obj);
Object.setPrototypeOf(func, Object.getPrototypeOf(obj));

其他人提供了当前的答案(“否”)和一些解决方法。就未来的一流支持而言,我向 es-discuss 邮件列表建议了这一点。那个时候这个想法并没有走得太远,但也许一些额外的兴趣会帮助这个想法再次动起来。

https://esdiscuss.org/topic/proposal-default-object-method