https://blog.csdn.net/sinat_41871344/article/details/82708684
https://www.cnblogs.com/null11/p/7498820.html
https://zhuanlan.zhihu.com/p/144832214
https://blog.csdn.net/csdnnews/article/details/107273877
UML类图

发布订阅代码实现
设计一个发布订阅模块
class Subscribe {}
jquery发布订阅
$.Callbacks()
- add
- remove
- fire
once
(function() {class Subscribe {constructor() {// 创建一个事件池,用来存储后面需要执行的方法this.pond = []}// 向事件池中添加方法add (func) {if(typeof func !== 'function') return// 重复处理const include = this.pond.some(item => item === func)if(!include) this.pond.push(func)}// 把事件池中的方法,按照顺序依次执行emit(...args) {const { length } = this.pondfor (let i = 0;i < length;i++) {const item = this.pond[i]if (typeof item !== 'function') {// 如果当前项不是函数,直接删除当前项,跳过当前循环this.pond.splice(i, 1)i--;continue;}// 三个以上的参数,call性能好于 applyitem.call(this, ...args)}}once(func) {if(typeof func !== 'function') returnfunc()this.remove(func)}// 从事件池中删除方法off(func) {this.pond}}// return 实例,暴露接口return () => new Subscribe()})()
使用发布订阅模式 ```javascript const sub = new Subscribe()
// 创建事件池 const pond = subscribe()
document.querySelect(‘.submit’).onclick = function(ev) { pond.emit(ev) } ```
数组塌陷问题
删除一个后,原有数组的每一项都向前移动了一位,
但还是按照原来的顺序循环,导致中间的某几项直接跳过,
jquery3.x修复了跳过的bug
