第一步:对象属性赋值为函数,对象内部函数控制年龄这一参数变化,同时成长事件也执行。
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);
这样的话,韩信就没有当小队长这个过程啦!
原文地址:https://www.cnblogs.com/hjj2ldq/p/9418602.html
时间: 2024-10-10 21:02:32