算法刷题
大厂面试还是很注重算法题的,尤其是字节跳动,算法是问的比较多的,关于算法,推荐《LeetCode》和《算法的乐趣》,这两本我也有电子版,字节跳动、阿里、美团等大厂面试题(含答案+解析)、学习笔记、Xmind思维导图均可以分享给大家学习。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
写在最后
最后,对所以做Java的朋友提几点建议,也是我的个人心得:
-
疯狂编程
-
学习效果可视化
-
写博客
-
阅读优秀代码
-
心态调整
ee.off(‘testoff’, toBeRemovedListener)
ee.emit(‘testoff’) // 此时事件监听已经被移除,不会再有console.log打印出来了
// 测试移除chifan的所有事件监听
ee.offAll(‘chifan’)
console.log(ee) // 此时可以看到ee.listeners已经变成空对象了,再emit发送chifan事件也不会有反应了
有了这个自己写的简单版本的EventEmitter
,我们就不用依赖第三方库啦。对了,vue
也可以帮我们做这样的事情。
const ee = new Vue();
ee.KaTeX parse error: Expected '}', got 'EOF' at end of input: …le.log(`吃饭了,我们去{address}吃${food}!`) })
ee.$emit(‘chifan’, ‘三食堂’, ‘铁板饭’)
所以我们可以单独new
一个Vue
的实例,作为事件管理器导出给外部使用。想测试的朋友可以直接打开vue
官网,在控制台试试,也可以在自己的vue
项目中实践下哦。
=========================================================================
其实仔细看看,EventEmitter
就是一个典型的发布订阅模式,实现了事件调度中心。发布订阅模式中,包含发布者,事件调度中心,订阅者三个角色。我们刚刚实现的EventEmitter
的一个实例ee
就是一个事件调度中心,发布者和订阅者是松散耦合的,互不关心对方是否存在,他们关注的是事件本身。发布者借用事件调度中心提供的emit
方法发布事件,而订阅者则通过on
进行订阅。
如果还不是很清楚的话,我们把代码换下单词,是不是变得容易理解一点呢?
class PubSub {
constructor() {
// 维护事件及订阅行为
this.events = {}
}
/**
-
注册事件订阅行为
-
@param {String} type 事件类型
-
@param {Function} cb 回调函数
*/
subscribe(type, cb) {
if (!this.events[type]) {
this.events[type] = []
}
this.events[type].push(cb)
}
/**
-
发布事件
-
@param {String} type 事件类型
-
@param {…any} args 参数列表
*/
publish(type, …args) {
if (this.events[type]) {
this.events[type].forEach(cb => {
cb(…args)
})
}
}
/**
-
移除某个事件的一个订阅行为
-
@param {String} type 事件类型
-
@param {Function} cb 回调函数
*/
unsubscribe(type, cb) {
if (this.events[type]) {
const targetIndex = this.events[type].findIndex(item => item === cb)
if (targetIndex !== -1) {
this.events[type].splice(targetIndex, 1)
}
if (this.events[type].length === 0) {
delete this.events[type]
}
}
}
/**
-
移除某个事件的所有订阅行为
-
@param {String} type 事件类型
*/
unsubscribeAll(type) {
if (this.events[type]) {
delete this.events[type]
}
}
}
最后,我们画个图加深下理解:
-
发布订阅模式中,对于发布者
Publisher
和订阅者Subscriber
没有特殊的约束,他们好似是匿名活动,借助事件调度中心提供的接口发布和订阅事件,互不了解对方是谁。 -
松散耦合,灵活度高,常用作事件总线
-
易理解,可类比于
DOM
事件中的dispatchEvent
和addEventListener
。
- 当事件类型越来越多时,难以维护,需要考虑事件命名的规范,也要防范数据流混乱。
========================================================================
观察者模式与发布订阅模式相比,耦合度更高,通常用来实现一些响应式的效果。在观察者模式中,只有两个主体,分别是目标对象Subject
,观察者Observer
。
-
观察者需
Observer
要实现update
方法,供目标对象调用。update
方法中可以执行自定义的业务代码。 -
目标对象
Subject
也通常被叫做被观察者或主题,它的职能很单一,可以理解为,它只管理一种事件。Subject
需要维护自身的观察者数组observerList
,当自身发生变化时,通过调用自身的notify
方法,依次通知每一个观察者执行update
方法。
按照这种定义,我们可以实现一个简单版本的观察者模式。
// 观察者
class Observer {
/**
-
构造器
-
@param {Function} cb 回调函数,收到目标对象通知时执行
*/
constructor(cb){
if (typeof cb === ‘function’) {
this.cb = cb
} else {
throw new Error(‘Observer构造器必须传入函数类型!’)
}
}
/**
- 被目标对象通知时执行
*/
update() {
this.cb()
}
}
// 目标对象
class Subject {
constructor() {
// 维护观察者列表
this.observerList = []
}
/**
-
添加一个观察者
-
@param {Observer} observer Observer实例
*/
addObserver(observer) {
this.observerList.push(observer)
}
/**
- 通知所有的观察者
*/
notify() {
this.observerList.forEach(observer => {
observer.update()
})
}
}
const observerCallback = function() {
console.log(‘我被通知了’)
}
算法刷题
大厂面试还是很注重算法题的,尤其是字节跳动,算法是问的比较多的,关于算法,推荐《LeetCode》和《算法的乐趣》,这两本我也有电子版,字节跳动、阿里、美团等大厂面试题(含答案+解析)、学习笔记、Xmind思维导图均可以分享给大家学习。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
写在最后
最后,对所以做Java的朋友提几点建议,也是我的个人心得:
-
疯狂编程
-
学习效果可视化
-
写博客
-
阅读优秀代码
-
心态调整