事件池 dom0 dom2

2020-01-14  本文已影响0人  wudongyu
        let _subscribe=(function(){
            //发布订阅类subscribe
            class Sub(){
                constructor(){
                    //创建事件池 存储后期需要执行的方法
                    this.$pond = [];
                    
                    //向事件池中追加方法   func(需要追加的方法 判断是否是方法 去重)
                    add(func){ 
                        /*some
                            arr.some(item=>{
                                return item>1
                            })
                            找true
                            是否存在满足条件的 true   循环结束没有 false 不检测空数组,不改变原始数组) 
                        
                        every
                            找false
                            找到后终止并返回false 每个对象是否满足条件
                        
                        find
                            arr.find(item=>{
                                return item.flag
                            })   
                            返回找到的满足条件的第一项,停止循环 不改变原始数组 循环完毕没找到返回undefined,不检测空数组)
                        
                        
                        includes(arr.includes(1)  true/false) filter(筛选 返回新数组,不改变旧的) 
                        
                        map(映射 返回新数组,不改变旧的) 
                        */
                        let flag = this.$pond.some(item=>{
                            return item===func
                        })
                        if(!flag){
                            this.$pond.push(func)
                        }
                        // !flag ? this.$pond.push(func) : null;
                    }

                    //移除事件池中的方法
                    remove(func){
                        //splice filter  浅拷贝 堆内存 引用类型
                        let $pond=this.$pond;
                        for(let i=0;i<$pond.length;i++){
                            let item=$pond[i];
                            if(item===func){
                                //移除 不改变方法顺序(改变顺序 删除当前项 将最后一项添加到当前位置,然后删除最后一位--性能优化) splice(i,n)
                                $pond.splice(i,1);  //导致数组塌陷-->假移除 赋值为null
                                $pond[i]=null//解决数组塌陷 伪删除 保证索引
                                break;  
                                //终止循环 区别return(终止当次循环)  
                            }
                        }
                    }

                    //通知事件池中的方法依次执行
                    fire(...args){   //...扩展运算符   args  传进来所有参数的数组(不确定参数有几个)
                        let $pond=this.$pond
                        for(let i=0;i<$pond.length;i++){
                            let item=$pond[i]
                            if(typeOf item!=='function'){
                                $pond.splice(i,1);  //再进行删除
                                i--;
                                continue;//跳过循环体中剩下的语句                                 
                            }
                            item.call(this,...args)  //this指向当前实例   单独传参 在三个或以上参数时 call的性能略优与apply  --apply  数组传参
                        }
                    }
                }
            }
            return function subscribe(){  //暴露外界使用 做普通函数
                return new Sub()
            } 
        })();//闭包 防止污染 冲突

        let s1 = _subscribe(); //创建实例 事件池
        document.querySelector('.submit').onclick=function(event){
            let evt=event?event:window.event;    //cancelBubble  取消事件冒泡        stopPropagation  取消事件冒泡和下沉
            s1.fire(evt) //执行事件池中的方法执行
        }
        s1.add(func)
        s1.remove(func)
上一篇下一篇

猜你喜欢

热点阅读