Как стать автором
Обновить

Комментарии 24

Можно еще использовать метод функций .bind
Да, можно. Иногда даже и нужно. Правда не все изменения окружения можно забиндить, плюс ко всему связывание получается слишком сильным. Ну и коллбэки не очень хороши, когда их много. А вообще, всё от задачи зависит.
Могут быть проблемы с кроссбраузерностью: bind() поддерживается только в ecmascript версии 5.
Реализация тривиальна.
Не спорю. Но стоит иметь в виду.
Отличное объяснение.
Только поставьте комментарий то что!!! это приведение к boolean, а то это весьма неявно )

Я в последнее время использую Backbone.Event
А зачем вообще приводить к Boolean если потом нет явного сравнения на истину (logtype === true), тут было бы достаточно this.type = logtype || «alert»;
1. Не самая удачная реализация паттерна Observer. Модифицировать прототипы встроенных объектов — дурной стиль.
2. В русской литературе принят перевод «Наблюдатель».
Поддержу. Гадить в прототипы объектов — плохо. Кое-где это еще бывает оправдано (например, добавление объектам методов, не поддерживаемых старыми браузерами), но это явно не тот случай.
На мой взгляд, куда лучше метод регистрации наблюдателя сделать в самом объекте Observable.
Вспомните обычные события DOM (elem.addEventListener). Посмотрите как это сделано в коде Firefox (всякие addObserver и addProgressListener).
А код то вообще пробовали проверять? В первом примере ошибка:
Function.prototype.subscribe = function(observable) {
    observable.observers.push(observer);    // <- observer не определен
    return this;
}
В остальных примерах тоже ошибки. Должно быть logger.write.subscribe(c.onChange, logger) вместо logger.write(c.onChange, logger).
Мда, и у этого поста 20 с лишним плюсов.
Действительно, оговорился. Спасибо, исправил.
Не надо делать яву из яваскрипта. В яваскрипте это обычно называют событиями и давно во всю используют.
чтобы заработал крайний пример


Какой-какой пример? 0_o
Может автор — лётчик? В авиации не говорят последний, говорят крайний.
А ещё моряки и, иногда, машинисты :)
Очень перемудрили. subscribe засунули почему-то в прототип функции. И даже не потому что «расширять прототипы — это плохо», а потому что ему там совсем не место. Зачем this равен текущей функции, если this по-умолчанию — не задан. Проходить массивы через for (var i in this.observers) — дурной тон.
И правильно люди выше сказали — JavaScript — не Java.

element.addEvent( 'click', object.method, object );


Где интерфейс такой:
addEvent( String event, Function callback[, Object context = null] );
Согласен автор перемудрил, я делаю обычно так (покажу упрощенно):

function myClass {
   this.listeners = new Array();
   this.args = new Array();
   this.objs  = new Array();//Объекты, которые будет играть роль объекта this в функции
}

myClass.prototype.addListener = function (func, arg, obj) {
   this.listeners.push(func);
   this.objs.push(obj);
   this.args.push(arg);
}

myClass.prototype.funcEvent = function () {
   //тут чего-то делаем
   ...
   //вызываем слушателей:
   for (var i = 0; i < this.listeners.length; i++) {
       this.listeners[i].apply(this.objs[i], this.args[i]);
   }
}

//В коде
var o = new MyClass();
//Делаем подписки
o.addListener(func1, ['arg1', 'arg2']);
o.addListener(func2, ['arg1', 'arg2'], obj);
...
o.funcEvent();

func1 () {
...
}

func2 () {
...
}
круто.
но тут же имелось в виду, чтобы сделать паттерн самому.
Ну я не критикую, просто даю ссылку на отличное, удобное, протестированное решение =)
Меня несколько смущает образование дырок в массивах args и objs, если аргументы или контекст вызова не заданы, а так — тоже вариант.
дырок не будет, будут null'ы
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории