自己手写一个简便化订阅与发布

/*判断类型*/
function toType(v) {
    if (arguments.length === 1) {
        var type = Object.prototype.toString.call(v);
        return type.slice(8, type.length - 1);
    }
}
/*构造实例对象*/
function PubSup(options) {
    if (options) {
        this.options = options;
    }
}
function ast() {
    return toType(arguments[0]) === 'String' || toType(arguments[0]) === 'Array';
}
function aft() {
    return toType(arguments[0]).indexOf('Function') !== -1 || toType(arguments[0]) === 'Array';
}
PubSup.prototype = {
    constructor: PubSup,
    /*订阅 绑定*/
    $on: function () {
        var args = arguments;
        if (args.length && this.options) {
            try {
                if (ast(args[0]) && aft(args[1])) {
                    args[0] = toType(args[0]) === 'String' ? [args[0]] : args[0];
                    args[1] = toType(args[1]).indexOf('Function') !== -1 ? [args[1]] : args[1];
                    for (var w = 0; w < args[0].length; w++) {
                        if (/(.*)/.test(args[0][w])) {
                            if (toType(args[1][w]).indexOf('Function') !== -1) {
                                this.options[args[0][w]] = args[1][w];
                            }
                        }
                    }
                }
            } catch (err) {

            }
        }
    },
    /*发布 引用*/
    $emit: function () {
        var args = arguments;
        if (args.length) {
            try {
                if (ast(args[0])) {
                    args[0] = toType(args[0]) === 'String' ? [args[0]] : args[0];
                    if (args[0]) {
                        var args_ = [...args].slice(1);
                        for (var w = 0; w < args[0].length; w++) {
                            if (this.options.hasOwnProperty(args[0][w])) {
                                var ef = this.options[args[0][w]];
                                if (toType(ef).indexOf('Function') !== -1) {
                                    var rd = ef(...args_);
                                    /*判断你的返回在如果是布尔值的话,并且为true 那么就删除该队列 就相当于once(一次性的)*/
                                    if (toType(rd) === 'Boolean' && rd) {
                                        this.delete(args[0][w]);
                                    }
                                    return rd;
                                }
                            }
                        }
                    }
                }
            } catch (err) { }
        }
    },
    /*取消订阅 解绑*/
    off: function () {
        var args = arguments;
        if (args.length) {
            try {
                if (ast(args[0])) {
                    args[0] = toType(args[0]) === 'String' ? [args[0]] : args[0];
                    if (args[0]) {
                        for (var w = 0; w < args[0].length; w++) {
                            if (this.options.hasOwnProperty(args[0][w])) {
                                this.delete(args[0][w])
                            }
                        }
                    }
                }
            } catch (err) { }
        }
    },
    /*删除堆栈中的队列*/
    delete: function () {
        try { delete this.options[arguments[0]] } catch (err) { }
    },
    /*清楚全部堆栈中的队列*/
    clear() {
        if (this.options) {
            this.options = {};
        }
    }
}
/*使用 通过new 字符 实例化*/
var PubSup= new PubSup({}/*储存队列,容器把订阅的队列放在该对象中*/);
console.log(PubSup)		
PubSup.$on('a',function(){
console.log(1);
/*返回值为true*/
return true;
})
PubSup.$on('ab',function(){
console.log(2);
})
PubSup.$emit('a');
// PubSup.off(['a','b']) /*也可以删除多个*/
PubSup.$emit('ab');
PubSup.off(['ab']);
PubSup.$emit('ab');

如图

在这里插入图片描述

在这里插入图片描述