Можно ли унаследовать от объекта функции javascript? - PullRequest
3 голосов
/ 24 февраля 2012

Можно ли сделать мою собственную реализацию функции в javascript?Иметь объект javascript, такой как объект php, с магическим методом __invoke?

  A = function(){};
  A.prototype = new Function();

  var a = new A();
  alert( a instanceof Function ); // true
  a(); // exception

Не могу ответить на свой вопрос ... Есть ответ:

Извините за всех, но я нашелхороший способ для моей задачи (я был в нескольких шагах от ответа, когда отправил вопрос).Я не удаляю вопрос, надеюсь, кто-то потратит меньше времени, чем я.

  A = function()
  {
    var f = function() { alert( 'f called' ) };
    f.__proto__ = A.prototype;
    return f;
  };

  A.prototype = Function( );
  A.prototype.method = function() { alert( 'method called' ) };

  var a = new A();
  alert( a instanceof Function ); // true
  alert( a instanceof A ); // true
  a(); // f called
  a.method(); // method called 

Если это вопрос новичка, пожалуйста, пришлите мне письмо, и я его удалю.Спасибо!

Ответы [ 2 ]

0 голосов
/ 24 февраля 2012

Как насчет этого:

function MyFunction ( f ) {
    _.extend( f, MyFunction.prototype );
    return f;
};

MyFunction.prototype.method = function () {
    alert( 'method called' );
};

var func = MyFunction( function () {
    alert( 'function called' );
});

Живая демоверсия: http://jsfiddle.net/nZczW/

Итак, вы создаете свои пользовательские функции, передавая их в свой конструктор пользовательских функций:

var func = MyFunction( function () {...} );

Методы определены (обычно) на прототипе конструктора:

MyFunction.prototype.foo = function () {...};

Внутри конструктора методы присваиваются непосредственно самой функции. (Я использовал underscore.js _.extend()). Таким образом, ваши функции по-прежнему наследуются непосредственно от Function.prototype.

Конечно, вы можете упростить этот шаблон:

var methods = { /* hash of methods */ };

var func = _.extend( function () { ... }, methods );
0 голосов
/ 24 февраля 2012

Разве это не было бы хорошо? К сожалению, нет хорошего способа сделать это.

Проблема, как вы, вероятно, заметили, заключается в том, что установка функции в качестве функции-конструктора prototype и последующий вызов функции-конструктора с new приводит к простому старому объекту, а не к вызываемому объекту функции.

Существует один возможный обходной путь, в зависимости от того, для чего вам это нужно. Это интересный трюк, но , вероятно, не очень хорошая идея для реального использования . Вы можете создать iframe и захватить Function из окна iframe. Теперь у вас есть «копия» Function, с которой вы можете делать все, что хотите, не портя вашу «настоящую» функцию Function.

var frame = document.createElement('iframe');
frame.id = frame.name = 'hacks';
frame.style.zIndex = '-1';
document.appendChild(frame);
var MyFunction = frames['hacks'].Function;
// add stuff to MyFunction and MyFunction.prototype
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...