js发布订阅模式

// 我们需要一个event对象,拥有on、remove、emit方法
var event = (function () {//采用闭包是用来存储注册的事件eventObjs
    eventObjs = {};
    return {
        /**注册事件,可以连续注册,可以注册多个事件*/
        on: function (type, handler) {
            // 如果注册过对应type事件,就直接把handler加在队列中,如果没有对应type类型,就先创建一个type类型的队列(数组),然后再handler添加进去
            // 不得不说,这代码很漂亮
            (eventObjs[type] || (eventObjs[type] = [])).push(handler);
        },
        /**移除事件,
         * -如果没有参数,移除所有事件,
         * -如果只带有 事件名 参数,就移除这个事件名下的所有事件,
         * -如果带有事件名 参数和事件处理函数名,那么久表示移除对应事件名下的某一个处理事件,
         */
        remove: function (type, handler) {
            if (arguments.length === 0) {//没有参数,移除所有事件
                eventObjs = {};
            } else if (arguments.length === 1) {//说明只有type:事件的类型,要移除此事件名下的所有处理函数
                eventObjs[type] = [];
            } else if (arguments.length === 2) {//移除type事件的handler函数
                // 使用循环移除所有的 该函数 对应的 type事件
                let _events = eventObjs[type];
                if (!_events) return;
                // 因为移除意向后,数组长度会自动变短,倒着循环,数组的序号不会受到影响
                for (let i = _events.length - 1; i >= 0; i--) {
                    if (_events[i] === handler) {
                        _events.splice(i, 1);
                    }
                }
            }
        },
        /**发射事件,触发事件,包装参数,传递给事件处理函数*/
        emit: function (type) {
            let args = Array.prototype.slice.call(arguments, 1);//拿到arguments从1开始后的所有参数,返回的是数组
            let _events = eventObjs[type];
            if (!_events) return;
            for (let i = 0; i < _events.length; i++) {
                // 如果要绑定上下文,就需要用到call或apply
                _events[i].apply(null, args);
            }
        },
    }

})();

使用方式

console.log(1);
event.on('click',() => console.log("第一个click事件"));
console.log(2);
event.on('click',() => console.log("第二个click事件"));
console.log(3);
event.emit('click');
console.log(4);

运行结果

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值