В приведенном ниже коде используется 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;