Можете ли вы сделать объект "вызываемым"?

Можно ли сделать объект вызываемым, реализуя либо call, либо apply на нем, или каким-либо другим способом? Например:.

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

...

obj (a, b);

Ответ 1

Нет, но вы можете добавить свойства в функцию, например

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

РЕДАКТИРОВАТЬ: чтобы "сделать" объект вызываемым, вам все равно придется выполнить описанное выше, но это может выглядеть примерно так:

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

И тогда вы просто используете функцию "func" вместо объекта. На самом деле все, что делает этот метод, это копирует свойства между двумя объектами, но... это может вам помочь.

Ответ 2

ES6 имеет лучшее решение для этого сейчас. Если вы создаете свои объекты по-другому (используя class, extend по типу "Function" ING), вы можете иметь вызываемый экземпляр.

Смотрите также: Как расширить Function с помощью классов ES6?

Ответ 3

Следуя той же строке @Max, но используя расширения ES6 для Object чтобы передать все свойства и прототип объекта obj в вызываемую func.

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

Ответ 4

Другие предоставили текущий ответ ("нет") и некоторые обходные пути. Что касается первоклассной поддержки в будущем, я предложил именно это в список рассылки es-обсуждения. В то время идея не зашла слишком далеко, но, возможно, какой-то дополнительный интерес поможет ее продвинуть снова.

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