Прежде всего, я не хочу добавлять методы к Function.prototype
. Это сделает их доступными для всех функций, и это не то, что я ищу.
В JavaScript вы можете создавать объекты с настраиваемыми прототипами, например:
function CustomObj() {}
CustomObj.prototype = {};
CustomObj.prototype.sayFoo = function () { return 'foo' };
var myCustomObj = new CustomObj(); //=> returns an object: {}
myCusomObj.sayFoo(); //=> 'foo'
Вы также можете создавать подобные массиву объекты с помощью собственных прототипов:
function CustomArr() {}
CustomArr.prototype = [];
CustomObj.prototype.sayFoo = function () { return 'foo' };
var myCustomArr = new CustomArr(); //=> returns an ordered object: []
myCustomArr.sayFoo(); //=> 'foo'
То, что я хотел бы сделать, это использовать какой-то конструктор для создания функции со своим собственным прототипом таким же образом. Однако следующее не работает:
function CustomFn() {}
CustomFn.prototype = function () {};
CustomFn.prototype.sayFoo = function () { return 'foo' };
var myCustomFn = new CustomFn(); //=> PROBLEM! returns an object: {}
myCustomFn.sayFoo(); //=> 'foo'
// ^^ Here, the prototype was applied but the output was not a function.
myCustomFn(); //=> TypeError: object is not a function
Итак, есть ли способ сделать то, что я пытаюсь сделать?
UPDATE
Возможно, есть другой способ, которым я мог бы задать этот вопрос, который сделает его немного яснее.
Проблема с идеей замыкания:
function makeFn() {
var output = function () { /* do some stuff */ };
output.foo = function () { /* do some stuff */ };
return output;
}
var specialFn = makeFn();
По сути, эта техника дает мне то, что я хочу. Однако проблема заключается в том, что каждый раз, когда я вызываю makeFn
, output.foo
должен быть создан как полностью независимая функция, которая берет свою собственную память. Валовой. Поэтому я мог бы вытащить этот метод из закрытия:
var protoMethods = {
"foo" : function () { /* do some stuff */ }
};
function makeFn() {
var output = function () { /* do some stuff */ };
for (var i in protoMethods) {
Object.prototype.hasOwnProperty.call(protoMethods, i) &&
(output[i] = protoMethods[i]);
}
return output;
}
var specialFn = makeFn();
Но теперь я должен вручную выполнять итерацию каждый раз, когда я вызываю makeFn
, что будет менее эффективным, чем если бы я мог просто назначить protoMethods
прототипом output
. Итак, с этим новым обновлением, любые идеи?