亮神知识库 亮神知识库
首页
  • 手写代码

    • 手写代码系列
  • 基础知识

    • 基础
    • JS底层
    • CSS
  • 原理
  • 浏览器
  • HTTP
  • 网络安全
  • babel
  • webpack基础
  • webpack进阶
  • Vite
  • TypeScript
  • Vue2
  • Vue3
  • Node基础

    • glob
    • 模块化机制
    • 事件循环
    • KOA2框架原理
    • Node子进程
    • cluster原理(了解)
  • 教育行业2021

    • B端
    • C端
    • 工具
  • 游戏行业2025
  • 刷题
  • 杂(待整理)
  • 学习
  • 面试
  • 实用技巧
  • 心情杂货
  • 年度总结
  • 友情链接
关于
  • 分类
  • 标签
  • 归档
  • 收藏
GitHub (opens new window)

亮神

前程明亮,未来可期
首页
  • 手写代码

    • 手写代码系列
  • 基础知识

    • 基础
    • JS底层
    • CSS
  • 原理
  • 浏览器
  • HTTP
  • 网络安全
  • babel
  • webpack基础
  • webpack进阶
  • Vite
  • TypeScript
  • Vue2
  • Vue3
  • Node基础

    • glob
    • 模块化机制
    • 事件循环
    • KOA2框架原理
    • Node子进程
    • cluster原理(了解)
  • 教育行业2021

    • B端
    • C端
    • 工具
  • 游戏行业2025
  • 刷题
  • 杂(待整理)
  • 学习
  • 面试
  • 实用技巧
  • 心情杂货
  • 年度总结
  • 友情链接
关于
  • 分类
  • 标签
  • 归档
  • 收藏
GitHub (opens new window)
  • 基础

  • 手写代码

    • 手写类型转换
    • 手写累加、累乘函数
    • 手写new
    • 手写深拷贝
    • 手写Object.create
    • 手写继承
    • 手写extends
    • 手写instanceof
    • 手写call、apply、bind
    • 手写jsonp
    • 手写getQueryString
    • 手写setInterval
    • 手写防抖与节流
    • 手写对象属性值迭代器
    • 手写分时函数
    • 手写事件委托
    • 手写图片懒加载
    • 手写原生Ajax请求
    • 手写AOP装饰函数
    • 手写柯里函数
    • 手写数组扁平化flat
    • 手写数组去重
    • 手写eventEmit类
    • 手写Vue数据响应式
    • 手写Vue nextTick
    • 手写Promise
  • JS底层深入

  • CSS

  • 基础
  • 手写代码
0zcl
2021-06-18

手写eventEmit类

注意

手写实现一个eventEmit类,包括如下几个方法:

  • on监听事件方法。
  • off取消监听事件方法。
  • emit触发事件方法。
  • once绑定一次事件监听方法

答:

class eventEmit {
  constructor() {
    this.event = {}
  }
  on(eventName, callback) {
    // 如果已存在事件名
    if (this.event[eventName]) {
      this.event[eventName].push(callback)
      return
    }
     this.event[eventName] = [callback]
  }

  off(eventName) {
    const eventList = this.event[eventName]
    if (eventList && eventList.length) {
      this.event[eventName] = []
    }
  }

  emit(eventName, ...params) {
    const eventList = this.event[eventName]
    if (eventList && eventList.length) {
      for (let index=0, len=eventList.length; index<len; index++) {
        eventList[index].apply(this, params) // this 为evnet实例
      }
    }
  }

  once(eventName, callback) {
    const fn = () => {
      this.off(eventName)
      callback()
    }
    this.on(eventName, fn)
  }
}
// 测试
const event = new eventEmit()
event.on('zcl', function() {
  console.log('this is zcl', arguments)
})
event.emit('zcl') // this is zcl
event.emit('zcl', 'arg1', 'arg2') // this is zcl Arguments(2) ["arg1", "arg2", callee: ƒ, Symbol(Symbol.iterator): ƒ]
event.off('zcl')
event.emit('zcl')
event.once('js', () => {
  console.log('this is JS')
})
event.emit('js') // this is JS
event.emit('js')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

注意:

  1. emit传入的参数需要 传给监听的事件
  2. once接入,重写了on监听的事件。新的事件fn,在调用旧的事件之前先把eventName对应的事件队列清空。个人理解其思想上和前几节复习到的AOP装饰函数异曲同工
  3. 监听器函数被调用时,this 关键词会被指向监听器所绑定的 EventEmitter 实例. 官网 (opens new window)
编辑 (opens new window)
上次更新: 2025/07/17, 07:17:44
手写数组去重
手写Vue数据响应式

← 手写数组去重 手写Vue数据响应式→

最近更新
01
2024年
07-20
02
2023年
07-20
03
2022年
07-20
更多文章>
Theme by Vdoing | Copyright © 2025-2025 亮神 | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式