Skip to content

Commit 5fba181

Browse files
feat: update
1 parent 5efc578 commit 5fba181

File tree

4 files changed

+153
-94
lines changed

4 files changed

+153
-94
lines changed

docs/.vuepress/config.js

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ module.exports = {
9090
base: '/blog/',
9191
title: '前端学习总结',
9292
description: '前端学习总结',
93+
// theme: 'vuepress-theme-lemon',
9394
head: [['link', { rel: 'icon', href: 'https://cdn.wangyaxing.cn/icon-128x128.png' }]],
9495
themeConfig: {
9596
sidebarDepth: 2,
@@ -180,9 +181,10 @@ module.exports = {
180181
['/jsCode/实现一个轮播图', '实现一个轮播图'],
181182
['/jsCode/放大镜效果', '放大镜效果'],
182183
['/jsCode/LazyMan', '实现一个LazyMan'],
184+
['/jsCode/发布-订阅模式的实现', '发布-订阅模式的实现'],
183185
],
184186
'/interview/': [
185-
['/interview/', '面试题专题'],
187+
['/interview/', '前端相关'],
186188
{
187189
title: 'CSS',
188190
collapsable: true,
@@ -261,14 +263,14 @@ module.exports = {
261263
['/interview/笔试题/6', '笔试题4'],
262264
],
263265
},
264-
{
265-
title: '面经分享',
266-
collapsable: true,
267-
children: [
268-
['/interview/面经/2017', '2017年面试总结'],
269-
['/interview/面经/2020-面试', '2020年面试总结'],
270-
],
271-
},
266+
// {
267+
// title: '面经分享',
268+
// collapsable: true,
269+
// children: [
270+
// ['/interview/面经/2017', '2017年面试总结'],
271+
// ['/interview/面经/2020-面试', '2020年面试总结'],
272+
// ],
273+
// },
272274
],
273275
'/100day/': [
274276
['/100day/', '100天计划专题'],

docs/README.md

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,15 @@
22
home: true
33
heroText: 前端学习总结
44
heroImage: ./logo.jpeg
5-
tagline:
5+
tagline:
66
actionText: 快速上手 →
77
actionLink: /algorithm/
88
features:
9-
- title: 算法系列
10-
details: JavaScript实现常见一些算法题,主要来自 leetcode和剑指offer
11-
- title: 手写代码系列
12-
details: JS手写代码系列,比如手写节流,防抖,深拷贝等等
13-
- title: 面试题系列
14-
details: 常见的面试题总结。
15-
- title: 100天系列
16-
details: 每天一个知识点的原理解析+一道算法题或者一篇一类问题(算法)的总结。
17-
footer: MIT Licensed | Copyright © 2020-present 木子星兮
18-
---
9+
- title: 算法系列
10+
details: JavaScript实现常见一些算法题,主要来自 leetcode和剑指offer
11+
- title: 编程题
12+
details: JS手写代码系列,比如手写节流,防抖,深拷贝等等
13+
- title: 前端知识
14+
details: 基础知识总结。
15+
footer: MIT Licensed | Copyright © 2022-present OneStar
16+
---

docs/interview/README.md

Lines changed: 69 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,84 @@
1-
21
### CSS
3-
- [CSS基础知识点](./CSS/CSS基础知识点.md)
4-
- [伪类和伪元素](./CSS/伪类和伪元素.md)
5-
- [实现固定宽高比(`width: height = 4: 3`)的div,怎么设置](./CSS/实现固定宽高比的div.md)
6-
- [CSS选择器](./CSS/CSS选择器.md)
7-
- [CSS解析规则](./CSS/CSS解析规则.md)
8-
- [`flex: 1` 完整写法](./CSS/flex.md)
9-
- [`display: none``visibility:hidden`的区别](./CSS/display:none和visibility:hidden的区别.md)
10-
- [常见布局的实现](./CSS/常见CSS布局的实现)
11-
- `em` `rem` `vh` `vw` `calc()` `line-height` 百分比
12-
- `rem`实现原理及相应的计算方案
13-
- 清除浮动方法及原理
14-
- `postcss`是什么
15-
- `css modules`
16-
- `CSS`预处理器
17-
- CSS 中的 `vertical-align` 有哪些值?它在什么情况下才能生效?
18-
- BFC(块格式化上下文)
192

3+
- [CSS 基础知识点](./CSS/CSS基础知识点.md)
4+
- [伪类和伪元素](./CSS/伪类和伪元素.md)
5+
- [实现固定宽高比(`width: height = 4: 3`)的 div,怎么设置](./CSS/实现固定宽高比的div.md)
6+
- [CSS 选择器](./CSS/CSS选择器.md)
7+
- [CSS 解析规则](./CSS/CSS解析规则.md)
8+
- [`flex: 1` 完整写法](./CSS/flex.md)
9+
- [`display: none``visibility:hidden`的区别](./CSS/display:none和visibility:hidden的区别.md)
10+
- [常见布局的实现](./CSS/常见CSS布局的实现)
11+
- `em` `rem` `vh` `vw` `calc()` `line-height` 百分比
12+
- `rem`实现原理及相应的计算方案
13+
- 清除浮动方法及原理
14+
- `postcss`是什么
15+
- `css modules`
16+
- `CSS`预处理器
17+
- CSS 中的 `vertical-align` 有哪些值?它在什么情况下才能生效?
18+
- BFC(块格式化上下文)
2019

2120
## JavaScript
22-
- [从JS底层理解var,const,let](./JavaScript/从JS底层理解var,const,let.md)
23-
- [赋值、浅拷贝、深拷贝区别](./JavaScript/赋值、浅拷贝、深拷贝区别.md)
24-
- [三行代码实现add(1)(2)(3)](./JavaScript/函数柯里化.md)
25-
- [一文理解this&call&apply&bind](./JavaScript/一文理解this&call&apply&bind.md)
26-
- [typeof和instanceof原理](./JavaScript/typeof和instanceof原理.md)
27-
- [import和require](./JavaScript/import和require.md)
28-
- [setTimeout和requestAnimationFrame](./JavaScript/setTimeout和requestAnimationFrame.md)
29-
- [for...of原理解析](./JavaScript/for...of原理解析.md)
30-
- [Generator函数](./JavaScript/Generator函数.md)
31-
- [async原理解析](./JavaScript/async原理解析.md)
32-
- [详解ES6中的class](./JavaScript/详解ES6中的class.md)
33-
- [装饰器](./JavaScript/装饰器.md)
34-
- [JavaScript的几种创建对象的方式](./JavaScript/JavaScript的几种创建对象的方式.md)
35-
- [JavaScript的几种继承方式](./JavaScript/JavaScript的几种继承方式.md)
36-
- [事件循环机制](./JavaScript/事件循环机制.md)
21+
22+
- [从 JS 底层理解 var,const,let](./JavaScript/从JS底层理解var,const,let.md)
23+
- [赋值、浅拷贝、深拷贝区别](./JavaScript/赋值、浅拷贝、深拷贝区别.md)
24+
- [三行代码实现 add(1)(2)(3)](./JavaScript/函数柯里化.md)
25+
- [一文理解 this&call&apply&bind](./JavaScript/一文理解this&call&apply&bind.md)
26+
- [typeof 和 instanceof 原理](./JavaScript/typeof和instanceof原理.md)
27+
- [import 和 require](./JavaScript/import和require.md)
28+
- [setTimeout 和 requestAnimationFrame](./JavaScript/setTimeout和requestAnimationFrame.md)
29+
- [for...of 原理解析](./JavaScript/for...of原理解析.md)
30+
- [Generator 函数](./JavaScript/Generator函数.md)
31+
- [async 原理解析](./JavaScript/async原理解析.md)
32+
- [详解 ES6 中的 class](./JavaScript/详解ES6中的class.md)
33+
- [装饰器](./JavaScript/装饰器.md)
34+
- [JavaScript 的几种创建对象的方式](./JavaScript/JavaScript的几种创建对象的方式.md)
35+
- [JavaScript 的几种继承方式](./JavaScript/JavaScript的几种继承方式.md)
36+
- [事件循环机制](./JavaScript/事件循环机制.md)
3737

3838
### HTTP
39-
- [HTTP1.x、HTTP2、HTTP3](./HTTP/HTTP1.x、HTTP2、HTTP3.md)
40-
- [HTTPS](./HTTP/HTTPS.md)
41-
- [三次握手,四次挥手,为什么是三次和四次](./HTTP/三次握手,四次挥手,为什么是三次和四次)
42-
- [HTTP 的请求方法有哪些?GET和POST区别?](./HTTP/HTTP请求方法)
43-
- [HTTP状态码](./HTTP/HTTP状态码)
44-
- [Web安全之XSS](./HTTP/Web安全之XSS)
45-
- [Web安全之CSRF](./HTTP/Web安全之CSRF)
46-
- [TCP和UDP的区别](./HTTP/TCP和UDP)
39+
40+
- [HTTP1.x、HTTP2、HTTP3](./HTTP/HTTP1.x、HTTP2、HTTP3.md)
41+
- [HTTPS](./HTTP/HTTPS.md)
42+
- [三次握手,四次挥手,为什么是三次和四次](./HTTP/三次握手,四次挥手,为什么是三次和四次)
43+
- [HTTP 的请求方法有哪些?GET 和 POST 区别?](./HTTP/HTTP请求方法)
44+
- [HTTP 状态码](./HTTP/HTTP状态码)
45+
- [Web 安全之 XSS](./HTTP/Web安全之XSS)
46+
- [Web 安全之 CSRF](./HTTP/Web安全之CSRF)
47+
- [TCP 和 UDP 的区别](./HTTP/TCP和UDP)
4748

4849
### Vue
49-
- [简单通俗理解vue3.0中的Proxy](./Vue/简单通俗理解vue3.0中的Proxy.md)
50-
- [keep-alive的实现原理及LRU缓存策略](./Vue/keep-alive的实现原理及LRU缓存策略.md)
51-
- [nextTick的原理及运行机制](./Vue/nextTick的原理及运行机制)
5250

51+
- [简单通俗理解 vue3.0 中的 Proxy](./Vue/简单通俗理解vue3.0中的Proxy.md)
52+
- [keep-alive 的实现原理及 LRU 缓存策略](./Vue/keep-alive的实现原理及LRU缓存策略.md)
53+
- [nextTick 的原理及运行机制](./Vue/nextTick的原理及运行机制)
5354

5455
### React
5556

56-
- setState原理,什么时候同步,什么时候异步
57-
- JSX原理,为什么自定义的React组件必须大写
58-
- 虚拟DOM,diff算法
59-
- 虚拟DOM是什么
60-
- React diff原理,如何从 O(n^3)变成 O(n)
61-
- 为什么要使用Key,key有什么好处
62-
63-
- 生命周期(16版本之前和之后的)
64-
- React事件机制
65-
- React如何实现自己的事件机制
66-
- React事件和原生事件有什么区别
67-
- React 事件中为什么要绑定 this 或者 要用箭头函数, 他们有什么区别
68-
- fiber
69-
- [4个问题带你进阶ReactHooks](./React/4个问题带你进阶ReactHooks.md)
70-
- immber和immutable
71-
- 受控组件和非受控组件区别
72-
- redux,redux 和 mobx 区别,为什么选择 redux
73-
- Vue和React的区别
74-
75-
76-
57+
- setState 原理,什么时候同步,什么时候异步
58+
- JSX 原理,为什么自定义的 React 组件必须大写
59+
- 虚拟 DOM,diff 算法
60+
- 虚拟 DOM 是什么
61+
- React diff 原理,如何从 O(n^3)变成 O(n)
62+
- 为什么要使用 Key,key 有什么好处
63+
- 生命周期(16 版本之前和之后的)
64+
- React 事件机制
65+
- React 如何实现自己的事件机制
66+
- React 事件和原生事件有什么区别
67+
- React 事件中为什么要绑定 this 或者 要用箭头函数, 他们有什么区别
68+
- fiber
69+
- [4 个问题带你进阶 ReactHooks](./React/4个问题带你进阶ReactHooks.md)
70+
- immber 和 immutable
71+
- 受控组件和非受控组件区别
72+
- redux,redux 和 mobx 区别,为什么选择 redux
73+
- Vue 和 React 的区别
7774

7875
### 强烈推荐的文章
79-
- [(建议收藏)TCP协议灵魂之问,巩固你的网路底层基础](https://juejin.im/post/5e527c58e51d4526c654bf41)
80-
- [(1.6w字)浏览器灵魂之问,请问你能接得住几个?](https://juejin.im/post/5df5bcea6fb9a016091def69)
81-
- [中高级前端大厂面试秘籍,为你保驾护航金三银四,直通大厂(上)](https://juejin.im/post/5c64d15d6fb9a049d37f9c20)
82-
- [(中篇)中高级前端大厂面试秘籍,寒冬中为您保驾护航,直通大厂](https://juejin.im/post/5c92f499f265da612647b754)
83-
- [(下篇)中高级前端大厂面试秘籍,寒冬中为您保驾护航,直通大厂](https://juejin.im/post/5cc26dfef265da037b611738)
84-
- [看完跳槽少说涨 5 K,前端面试从准备到谈薪完全指南(近万字精华)](https://juejin.im/post/5dfef50751882512444027eb)
85-
- [前端该如何准备数据结构和算法?](https://juejin.im/post/5d5b307b5188253da24d3cd1)
86-
- [在阿里我是如何当面试官的(持续更新)](https://juejin.im/post/5e6ebfa86fb9a07ca714d0ec)
8776

88-
### 个人面经分享
89-
- [2017年面试总结](./面经/2017.md)
77+
- [(建议收藏)TCP 协议灵魂之问,巩固你的网路底层基础](https://juejin.im/post/5e527c58e51d4526c654bf41)
78+
- [(1.6w 字)浏览器灵魂之问,请问你能接得住几个?](https://juejin.im/post/5df5bcea6fb9a016091def69)
79+
- [中高级前端大厂面试秘籍,为你保驾护航金三银四,直通大厂(上)](https://juejin.im/post/5c64d15d6fb9a049d37f9c20)
80+
- [(中篇)中高级前端大厂面试秘籍,寒冬中为您保驾护航,直通大厂](https://juejin.im/post/5c92f499f265da612647b754)
81+
- [(下篇)中高级前端大厂面试秘籍,寒冬中为您保驾护航,直通大厂](https://juejin.im/post/5cc26dfef265da037b611738)
82+
- [看完跳槽少说涨 5 K,前端面试从准备到谈薪完全指南(近万字精华)](https://juejin.im/post/5dfef50751882512444027eb)
83+
- [前端该如何准备数据结构和算法?](https://juejin.im/post/5d5b307b5188253da24d3cd1)
84+
- [在阿里我是如何当面试官的(持续更新)](https://juejin.im/post/5e6ebfa86fb9a07ca714d0ec)
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
## 发布-订阅模式的实现
2+
3+
写出一个同时拥有 on、emit 和 off 的 EventEmitter
4+
5+
```js
6+
class myEventEmitter {
7+
constructor() {
8+
// eventMap 用来存储事件和监听函数之间的关系
9+
this.eventMap = {};
10+
}
11+
12+
// type 这里就代表事件的名称
13+
on(type, handler) {
14+
// hanlder 必须是一个函数,如果不是直接报错
15+
16+
if (!(handler instanceof Function)) {
17+
throw new Error('请传一个函数');
18+
}
19+
// 判断 type 事件对应的队列是否存在
20+
if (!this.eventMap[type]) {
21+
// 若不存在,新建该队列
22+
this.eventMap[type] = [];
23+
}
24+
// 若存在,直接往队列里推入 handler
25+
this.eventMap[type].push(handler);
26+
}
27+
28+
// 别忘了我们前面说过触发时是可以携带数据的,params 就是数据的载体
29+
emit(type, params) {
30+
// 假设该事件是有订阅的(对应的事件队列存在)
31+
if (this.eventMap[type]) {
32+
// 将事件队列里的 handler 依次执行出队
33+
this.eventMap[type].forEach((handler, index) => {
34+
// 注意别忘了读取 params
35+
handler(params);
36+
});
37+
}
38+
}
39+
40+
off(type, handler) {
41+
if (this.eventMap[type]) {
42+
this.eventMap[type].splice(this.eventMap[type].indexOf(handler) >>> 0, 1);
43+
}
44+
}
45+
}
46+
```
47+
48+
下面我们对 myEventEmitter 进行一个简单的测试,创建一个 myEvent 对象作为 myEventEmitter 的实例,然后针对名为 “test” 的事件进行监听和触发:
49+
50+
```js
51+
// 实例化 myEventEmitter
52+
const myEvent = new myEventEmitter();
53+
54+
// 编写一个简单的 handler
55+
const testHandler = function(params) {
56+
console.log(`test事件被触发了,testHandler 接收到的入参是${params}`);
57+
};
58+
59+
// 监听 test 事件
60+
myEvent.on('test', testHandler);
61+
62+
// 在触发 test 事件的同时,传入希望 testHandler 感知的参数
63+
myEvent.emit('test', 'newState');
64+
```

0 commit comments

Comments
 (0)