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

  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);

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

写一个addEventListener以及removeEventListener的更多相关文章

  1. 事件监听addEventListener()和removeEventListener() ---------1

    一直想写一个原生事件监听的记录,方便以后看,不愿意写主要是事件监听的单词太长,记起来好难记每次都要查,这次把知道的写完了,来这里查好了,以后要是理解的更透彻了,就再补全好了 首先,DOM0级事件和DO ...

  2. (转)addEventListener()与removeEventListener()详解

    转自:http://www.111cn.net/wy/js-ajax/48004.htm addEventListener()与removeEventListener()用于处理指定和删除事件处理程序 ...

  3. 如何写一个跨浏览器的事件处理程序 js

    如何 写一个合格的事件处理程序,看如下代码: EventUtil可以直接拿去用 不谢 <!DOCTYPE html> <html> <head> <title ...

  4. addEventListener()与removeEventListener(),追加事件和删除追加事件

    addEventListener()与removeEventListener()用于追加事件和删除追加.所有的DOM节点中都包含这两种方法,并且它们都接受3个参数:要处理的事件名.作为事件处理程序的函 ...

  5. 手写一个虚拟DOM库,彻底让你理解diff算法

    所谓虚拟DOM就是用js对象来描述真实DOM,它相对于原生DOM更加轻量,因为真正的DOM对象附带有非常多的属性,另外配合虚拟DOM的diff算法,能以最少的操作来更新DOM,除此之外,也能让Vue和 ...

  6. 兼容8事件绑定与解绑addEventListener、removeEventListener和ie的attachEvent、detachEvent

    兼容8事件绑定与解绑addEventListener.removeEventListener和ie的attachEvent.detachEvent   ;(function(){ // 事件绑定 bi ...

  7. 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”

    这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...

  8. js高级程序设计笔记之-addEventListener()与removeEventListener(),事件解除与绑定

    js高级程序设计笔记之-addEventListener()与removeEventListener(),事件解除与绑定 addEventListener()与removeEventListener( ...

  9. 用vue写一个仿app下拉刷新的组件

    如果你用vue弄移动端的页面,那么下拉刷新还是比较常见的场景,下面来研究如何写一个下拉刷新的组件(先上图); 由于节省大家的时间,样式就不贴出来了. html结构也不必介绍了,直接看代码吧-.- &l ...

随机推荐

  1. 3d Max 2010安装失败怎样卸载3dsmax?错误提示某些产品无法安装

    AUTODESK系列软件着实令人头疼,安装失败之后不能完全卸载!!!(比如maya,cad,3dsmax等).有时手动删除注册表重装之后还是会出现各种问题,每个版本的C++Runtime和.NET f ...

  2. maya安装不了

    AUTODESK系列软件着实令人头疼,安装失败之后不能完全卸载!!!(比如maya,cad,3dsmax等).有时手动删除注册表重装之后还是会出现各种问题,每个版本的C++Runtime和.NET f ...

  3. C# a == b ? c :d 表示的意思

    a==b 为true,这个表达式返回c; a==b为false,这个表达式返回d. 相当于: if(a == b) { return c; } else { return d; }

  4. is 和 == 区别

    == 和 is 的区别 == 比较 比较的是两个值 适用于 列表​a = '[1:2]'b = '[1:2]'print(a == b) #True​​​​ 字典a = '{1,2,3}'b = '{ ...

  5. [转]LazyLoad.js及scrollLoading.js

    本文转自:http://blog.csdn.net/ning109314/article/details/7042829 目前图片延迟加载主要分两大块,一是触发加载(根据滚动条位置加载图片):二是自动 ...

  6. typescript的lambads解决this关键字找不到属性

    var people = { name: ["abc", "jack", "pepter", "jim"], getna ...

  7. JavaScript控制流及关键字与C语言之比较

    学习JavaScript控制流及关键字概念前,对有过C语言学习经验的同学来说,那么关键字,控制语句概念并不陌生.我们先来看看C语言吧: C语言的32个关键字和9种控制语句 9种控制语句: if.if- ...

  8. Spring中的一些常用接口

    一.ApplicationContextAware接口 注:可以在spring容器初始化的时候调用setApplicationContext方法,从而获得ApplicationContext中的所有b ...

  9. [Java][Servlet] Failed to destroy end point associated with ProtocolHandler ["http-nio-8080"]

    Background: Servlet version 3.1(3.0之后就有了@WebServlet注解) Error 严重: Failed to destroy end point associa ...

  10. if转switch

    if($a=="a") { echo "a"; } elseif ($a == "b") { echo "b"; } e ...