2010-07-22 3 views
5

Я экспериментировал с шаблоном проектирования в Javascript, который позволил бы мне иметь то, что, как представляется, одноэлементные функции, которые могут быть переопределены функциями экземпляра.A (несколько неясный) Вопрос о наследовании 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...} 

Но когда экземпляр экземпляра Даты первый:

>>> 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 
+1

Просто из любопытства; вы посмотрели на Yahoo! Библиотека событий? Я знаю, что это не совсем то, о чем вы спрашиваете ... но похоже, что вы просите о вас, может быть, вам не понадобится, если у вас есть приличная альтернатива? (http://developer.yahoo.com/yui/event/) – Steve

+0

@ На мой вопрос действительно не связано с привязкой событий как таковой, а скорее форма модуляции. Существуют определенные типы проводки событий, которые я хочу, чтобы иметь возможность вызывать как неявно, так и явно. Плюс я уже использую jQuery для событий, которые мне нравятся лучше, чем YUI. –

ответ

0

С 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); 
2

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

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

function a() 
{ 
    return 10; 
} 

a.e = "oO"; 

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

Чтобы получить доступ к электронному изнутри можно использовать вызываемое свойство из аргументов, например:

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

a.e = "Oo" 

a(); 
+0

Да, это странно; но тогда наследование Javascript вообще странно;) Мой вопрос: можете ли вы получить доступ к a.e из самой функции a()? Как бы вы это сделали, не используя полностью квалифицированное имя? –

+0

'arguments.callee' - это то, что я искал! Благодарю. –

Смежные вопросы