javascript设计模式之观察者模式

dom 的事件模式就是观察者模式

/*
 * 观察者模式又叫发布者-订阅者模式
 * 我发布一则消息,消息就在那里;你若订阅,我便发送。
*/

/*
 * js和dom之间的实现就是一种观察者模式;
 * 所有的dom元素都发布了事件,然后观察谁订阅了这个事件;
 * 例:div订阅了click事件
*/
document.getElementById("banner").onclick = function () {
    alert("div is clicked!");
};

原生实现

/*
 * js 观察者模式 又称 订阅/发布模式
 * 通过创建“可观察”对象,当发生一个感兴趣的事件时可将该事件通告给
 * 所有观察者,从而形成松耦合
*/
var pubsub = (function () {

    var q = {},
        topics = {},
        subUid = -1;

    // 发布方法
    q.publish = function (topic, args) {

        if (!topics[topic]) {
            return false;
        }

        var subscribers = topics[topic],
            len = subscribers ? subscribers.length : 0;

        while (len--) {
            subscribers[len].func(topic, args);
        }

        return true;
    };

    // 订阅方法
    q.subscribe = function (topic, func) {

        if (!topics[topic]) {
            topics[topic] = [];
        }

        var token = (++subUid).toString();

        topics[topic].push({
            token: token,
            func: func
        });

        return token;
    };

    //退订方法
    q.unsubscribe = function (token) {
        for (var m in topics) {
            if (topics[m]) {
                for (var i = 0, j = topics[m].length; i < j; i++) {
                    if (topics[m][i].token === token) {
                        topics[m].splice(i, 1);
                        return token;
                    }
                }
            }
        }
        return false;
    };

    return q;
})();


pubsub.subscribe("broadcast", function (topic, data) {
    console.log(topic + " : " + data);    // broadcast : hello world
});

pubsub.publish("broadcast", "hello world");

jQuery版本

// jquery 版本
(function ($) {

    var o = $({});

    // 订阅既是事件绑定(观察者)
    $.subscribe = function () {
        o.on.apply(o, arguments);  // on
    };

    $.unsubscribe = function () {
        o.off.apply(o, arguments);
    };

    // 发布既是事件触发
    $.publish = function () {
        o.trigger.apply(o, arguments);  // trigger
    };
} (jQuery));

$.subscribe("j-bro", function (e, data) {
    console.log(data);    // jquery broadcast
});

$.publish("j-bro", "jquery broadcast");
$.publish("j-bro", "jquery broadcast again");
原文地址:https://www.cnblogs.com/xiankui/p/3964301.html