• 写一个addEventListener以及removeEventListener


    第一步:对象属性赋值为函数,对象内部函数控制年龄这一参数变化,同时成长事件也执行。

      class Person{
            constructor(){
                this.name = '';
                this.age = 0;
                this.growup()//不断成长
                this.growEvent = null//成长经历的事情
            }
            setName(val){
                this.name = val
            }
            growup(){
                let _this = this;
                setInterval(()=>{
                    _this.age++;
                    if(_this.growEvent instanceof Function){//判断是不是函数
                        _this.growEvent()
                    }
                },100)
            }
            
        }
        let hx = new Person()
        hx.setName('韩信')
        hx.growEvent = function(){
            if(this.age == 18){
                console.log('开始参军啦')
            }
        }

    继续思考:成长事件只能接受一个函数,那么如果是多个函数呢?韩信要打仗,要建功立业的呀。可以很快的想到growEvent换成数组来接受多个函数。

    那么,growEvent就要靠Push进数组了,而不是粗暴的赋值了。成长事件执行的时候也不再是上门的_this.growEvent,而是循环了。

      class Person{
        	constructor(){
        		this.name = '';
        		this.age = 0;
        		this.growup()//不断成长
        		this.growEvent = []//需要接受多个函数
        	}
        	setName(val){
        		this.name = val
        	}
        	growup(){
        		let _this = this;
        		setInterval(()=>{
        			_this.age++;
        			_this.growEvent.forEach(cb=>{
        				if(cb instanceof Function){
        					cb.call(this)//需要注意更改this指向,不然指向window
        				}
        			})
        		},100)
        	}
        	
        }
        let hx = new Person()
        hx.setName('韩信')
        hx.growEvent.push(function(){
        	if(this.age == 18){
        		console.log('开始参军啦')
        	}
        })
        hx.growEvent.push(function(){
        	if(this.age == 20){
        		console.log('当上小队长啦')
        	}
        })
    

    上面的这种方式成长事件采用直接Push的方式看着好像有点辣眼睛,那么我们可以添加一个addEventListener方法来帮我们Push

    class Person{
            constructor(){
                this.name = '';
                this.age = 0;
                this.growup()//不断成长
                this.growEvent = []//需要接受多个函数
            }
            setName(val){
                this.name = val
            }
            growup(){
                let _this = this;
                setInterval(()=>{
                    _this.age++;
                    _this.growEvent.forEach(cb=>{
                        if(cb instanceof Function){
                            cb.call(this)//需要注意更改this指向,不然指向window
                        }
                    })
                },100)
            }
            addEventListener(cb){
                if(cb instanceof Function){
                    this.growEvent.push(cb)
                }
            }
            
        }
        let hx = new Person()
        hx.setName('韩信')
        hx.addEventListener(function(){
            if(this.age == 18){
                console.log('开始参军啦')
            }
        })
        hx.addEventListener(function(){
            if(this.age == 20){
                console.log('当上小队长啦')
            }
        })

    写到了这里看上去好像有点那啥的样子了。那么,假设成长事件需要一个名字呢?比如,hx,addEventListener("marry",funciton(){})

    那我们就需要继续对growEvent继续改装,改成对象形式,每个属性的属性值都是一个数组。

    在Push事件,以及执行事件的时候也要更改一下。

    class Person{
            constructor(){
                this.name = '';
                this.age = 0;
                this.growup()//不断成长
                this.growEvent = {}//需要接受多个函数
            }
            setName(val){
                this.name = val
            }
            growup(){
                let _this = this;
                setInterval(()=>{
                    _this.age++;
                    for(let i in _this.growEvent){
                        if(_this.growEvent[i] && _this.growEvent[i] instanceof Array){
                            _this.growEvent[i].forEach(cb=>{
                                if(cb instanceof Function){
                                    cb.call(this)//需要注意更改this指向,不然指向window
                                }
                            })
                        }
                    }
                    
                },100)
            }
            addEventListener(name,cb){
                if(name && cb instanceof Function){
                    if(this.growEvent[name]){
                        this.growEvent[name].push(cb)
                    }else{
                        this.growEvent[name] = []
                        this.growEvent[name].push(cb)
                    }
                }
            }
            
        }
        let hx = new Person()
        hx.setName('韩信')
        hx.addEventListener('army',function(){
            if(this.age == 18){
                console.log('开始参军啦')
            }
        })
        hx.addEventListener('lead',function(){
            if(this.age == 20){
                console.log('当上小队长啦')
            }
        })
        hx.addEventListener('lead',function(){
            if(this.age == 25){
                console.log('当上大队长啦')
            }
        })

    那么接下来要做的是如何removeEventListener 呢?一种方式是粗暴的直接清空数组,把多个事件同时清除。

    class Person{
            constructor(){
                this.name = '';
                this.age = 0;
                this.growup()//不断成长
                this.growEvent = {}//需要接受多个函数
            }
            setName(val){
                this.name = val
            }
            growup(){
                let _this = this;
                setInterval(()=>{
                    _this.age++;
                    for(let i in _this.growEvent){
                        if(_this.growEvent[i] && _this.growEvent[i] instanceof Array){
                            _this.growEvent[i].forEach(cb=>{
                                if(cb instanceof Function){
                                    cb.call(this)//需要注意更改this指向,不然指向window
                                }
                            })
                        }
                    }
                    
                },100)
            }
            addEventListener(name,cb){
                if(name && cb instanceof Function){
                    if(this.growEvent[name]){
                        this.growEvent[name].push(cb)
                    }else{
                        this.growEvent[name] = []
                        this.growEvent[name].push(cb)
                    }
                }
            }
            removeEventListener(name){
                if(name && this.growEvent.hasOwnProperty(name)){
                    this.growEvent[name] = []
                }
            }
        }
        let hx = new Person()
        hx.setName('韩信')
        hx.addEventListener('army',function(){
            if(this.age == 18){
                console.log('开始参军啦')
            }
        })
        hx.addEventListener('lead',function(){
            if(this.age == 20){
                console.log('当上小队长啦')
            }
        })
        hx.addEventListener('lead',function(){
            if(this.age == 25){
                console.log('当上大队长啦')
            }
        })
        hx.removeEventListener('army');

    上面这样的话,韩信就不会开始参军了,直接当小队长起步。

    但是这样做的话还是有点不好,包括js里的原生事件也是,移除监听的时候,是需要函数名称的。具名函数无论是在回调还是递归里都非常有用。

    class Person{
            constructor(){
                this.name = '';
                this.age = 0;
                this.growup()//不断成长
                this.growEvent = {}//需要接受多个函数
            }
            setName(val){
                this.name = val
            }
            growup(){
                let _this = this;
                setInterval(()=>{
                    _this.age++;
                    for(let i in _this.growEvent){
                        if(_this.growEvent[i] && _this.growEvent[i] instanceof Array){
                            _this.growEvent[i].forEach(cb=>{
                                if(cb instanceof Function){
                                    cb.call(this)//需要注意更改this指向,不然指向window
                                }
                            })
                        }
                    }
                    
                },100)
            }
            addEventListener(name,cb){
                if(name && cb instanceof Function){
                    if(this.growEvent[name]){
                        this.growEvent[name].push(cb)
                    }else{
                        this.growEvent[name] = []
                        this.growEvent[name].push(cb)
                    }
                }
            }
            removeEventListener(name,cbName){
                if(name && this.growEvent.hasOwnProperty(name)){
                    this.growEvent[name] = this.growEvent[name].filter(cb=>{
                        return cb != cbName
                    })
                }
            }
        }
        let hx = new Person()
        hx.setName('韩信')
        hx.addEventListener('army',function(){
            if(this.age == 18){
                console.log('开始参军啦')
            }
        })
        hx.addEventListener('lead',fn)
        function fn(){
            if(this.age == 20){
                console.log('当上小队长啦')
            }
        }
        hx.addEventListener('lead',function(){
            if(this.age == 25){
                console.log('当上大队长啦')
            }
        })
        hx.removeEventListener('lead',fn);

    这样的话,韩信就没有当小队长这个过程啦!

  • 相关阅读:
    c-free5
    node.js模块
    cd
    bower
    atom插件
    反射(操作MetaData)
    1.Html
    SQL语句 把一个表的数据复制到另外一个表里面
    Redis 可视化工具
    C# 多文件压缩包
  • 原文地址:https://www.cnblogs.com/hjj2ldq/p/9418602.html
Copyright © 2020-2023  润新知