(Немного неясный) вопрос наследования Javascript - PullRequest
5 голосов
/ 23 июля 2010

Я экспериментировал с шаблоном проектирования в Javascript, который позволил бы мне иметь то, что кажется одноэлементными функциями, которые могут быть переопределены функциями экземпляра.

Вот краткий пример:

Date.tomorrow = function () {
  return Date.today().add(1).days();
}

(function(p) {

  p.tomorrow = function() {
    var date = this.clone().clearTime();
    return date.equals(Date.tomorrow());
  }

})(Date.prototype);

Итак, есть две tomorrow() функции.При прямом вызове из функции Date:

>>> Date.tomorrow()
=>  Fri Jul 23 2010 00:00:00 GMT-0500 (CST) { _orient=1,  more...}

Но когда вы сначала создаете экземпляр экземпляра Date:

>>> var date = new Date()
>>> date.tomorrow()
=>  false

Я упускаю многое, так как уверен, что вы можете сказать,, но, надеюсь, вы поняли.Мой вопрос таков: каково отношение первой функции tomorrow() к объекту Date?К чему это конкретно привязано?

Допустим, вы делали это с обычной функцией, которая не была предназначена для конструктора.Можно ли вызвать расширенную функцию из исходной функции?

В функции конструктора вы можете сделать это:

this.constructor.functionName();

, но если функция не используется в качестве конструктораочевидно, что ссылка constructor не существует.Есть ли другой способ получить доступ к этой расширенной функции?

Толчком к этому вопросу является моя работа по реорганизации кода JS для проекта.Мы внедряем систему Sprockets , чтобы разделить наш исходный код на модули, в которых мы в основном декорируем базовое пространство имен вместо того, чтобы объединять все это в одно нечитаемое определение встроенного объекта.

У нас есть довольно эпически большая система обработки событий, которую приятно разделить на отдельные функции, но я бы предпочел не вызывать каждую функцию по отдельности;вместо этого я бы хотел суперфункцию, которая вызывает все подфункции за один раз.

Я всегда мог бы создать функцию all() или что-то для этого, но это выглядело бы намного чище из APIс точки зрения, если вызов функции верхнего уровня выполнял все вложенные к ней подфункции.


Благодаря ответу Франциско у меня теперь есть рабочая реализация того, о чем я думал.Вот пример, если кому-то было любопытно.

var Namespace = {};

var Namespace.wireup = (function () {

  return function () {
    var self = arguments.callee;
    self.eventWireup1();
    self.eventWireup2();
  };

})();

(function (W) {

  function eventWireup1 () { console.log('first function'); };
  function eventWireup2 () { console.log('second function'); };

  $.extend(W, {
    eventWireup1: eventWireup1,
    eventWireup2: eventWireup2
  });

})(Namespace.wireup);

Преимущество этого API в том, что вы можете сделать это:

>>> Namespace.wireup.eventWireup1();
=>  first function
>>> Namespace.wireup.eventWireup2();
=>  second function
>>> Namespace.wireup();
=>  first function
=>  second function

Ответы [ 2 ]

2 голосов
/ 23 июля 2010

Дата - это функция () объекта окна, и вы присоединяете к ней другую функцию. Странно, а?

Попробуйте это:

function a()
{
    return 10;
}

a.e = "oO";

typeof(a);
typeof(a.e);

Для доступа к e изнутри a вы можете использовать свойство callee из аргументов, например:

function a () {
    return arguments.callee.e;
}

a.e = "Oo"

a();
0 голосов
/ 21 ноября 2015

Поскольку arguments.callee устарело, я подумал, что мне следует обновить этот вопрос на примере того, что я перешел к тому, что более корректно и совместимо со строгим режимом.

var Namespace = {};

(function () {
  Namespace.wireup = function self () {
    self.eventWireup1();
    self.eventWireup2();
  }
})();

(function (self) {
  self.eventWireup1 = function () { console.log('first function') }
  self.eventWireup2 = function () { console.log('second function') }
})(Namespace.wireup);
...