Приведенный ниже код использует Javascript для создания базового класса eventRaiser
, который имеет внутренние компоненты, необходимые для того, чтобы клиенты могли подписаться на события , и подклассы для вызова этих событий.Идея состоит в том, что другие классы, такие как ThingWithEvent
, будут наследоваться от eventRaiser
и предоставлять метод подписки, а также запускать метод повышения внутри системы.Функция инициализации jQuery демонстрирует это.
Как это написано, ничто не мешает клиенту напрямую вызывать событие.Другими словами, добавление er.raise("Y");
к функции инициализации jQuery вызывает событие Y без проблем.
В идеале я хотел бы сделать так, чтобы внешний код, взаимодействующий с eventRaiser
через некоторый класс, который наследовал от него, мог только подписываться на события, а не вызывать их.
Другими словами, я бы хотел, чтобы raise
был эквивалентом C # protected
- видимым только себе и классам, которые наследуют его.
Есть ли какое-то плавное закрытие ниндзя, которое я должен использовать для достижения этого, или я должен признать, что Javascript не предназначен для включения OO Encapulation, переименуйте raise
в _raise
, чтобы указать клиентскому коду, что _raise
является закрытым и не долженвызывать и двигаться дальше?
$(function() {
var er = new ThingWithEvent();
er.subscribe("X", function() { alert("Hello"); });
er.subscribe("X", function() { alert("World"); });
er.subscribe("Y", function() { alert("Not Called"); });
er.doSomething("X");
});
function eventRaiser() {
var events = {};
this.subscribe = function(key, func) {
if (!events[key])
events[key] = { name: key, funcs: [] };
events[key].funcs.push(func);
};
this.raise = function(key) {
if (!events[key]) return;
for (var i = 0; i < events[key].funcs.length; i++)
events[key].funcs[i]();
};
}
function ThingWithEvent() {
eventRaiser.call(this);
var self = this;
this.doSomething = function() {
alert("doing something");
self.raise("X");
}
}
function surrogate() { }
surrogate.prototype = eventRaiser;
ThingWithEvent.prototype = new surrogate();
ThingWithEvent.prototype.constructor = ThingWithEvent;