前端常见手写面试题(持续更新中)
实现简单路由
实现 forEach 方法
实现观察者模式
观察者模式(基于发布订阅模式) 有观察者,也有被观察者
观察者需要放到被观察者中,被观察者的状态变化需要通知观察者 我变化了 内部也是基于发布订阅模式,收集观察者,状态变化后要主动通知观察者
实现 apply 方法
思路: 利用
this
的上下文特性。apply
其实就是改一下参数的问题
基于 Generator 函数实现 async/await 原理
核心:传递给我一个
Generator
函数,把函数中的内容基于Iterator
迭代器的特点一步步的执行
数组中的数据根据 key 去重
给定一个任意数组,实现一个通用函数,让数组中的数据根据 key 排重:
实现
使用
实现 map 方法
回调函数的参数有哪些,返回值如何处理
不修改原来的数组
实现 redux-thunk
redux-thunk
可以利用redux
中间件让redux
支持异步的action
原生实现
参考:前端手写面试题详细解答
实现模板字符串解析功能
实现 filter 方法
实现 new 的过程
new 操作符做了这些事:
创建一个全新的对象
这个对象的
__proto__
要指向构造函数的原型 prototype执行构造函数,使用
call/apply
改变 this 的指向返回值为
object
类型则作为new
方法的返回值返回,否则返回上述全新对象
实现 every 方法
实现 findIndex 方法
实现发布订阅模式
简介:
发布订阅者模式,一种对象间一对多的依赖关系,但一个对象的状态发生改变时,所依赖它的对象都将得到状态改变的通知。
主要的作用(优点):
广泛应用于异步编程中(替代了传递回调函数)
对象之间松散耦合的编写代码
缺点:
创建订阅者本身要消耗一定的时间和内存
多个发布者和订阅者嵌套一起的时候,程序难以跟踪维护
实现的思路:
创建一个对象(缓存列表)
on
方法用来把回调函数fn
都加到缓存列表中emit
根据key
值去执行对应缓存列表中的函数off
方法可以根据key
值取消订阅
测试用例
发布订阅者模式和观察者模式的区别?
发布/订阅模式是观察者模式的一种变形,两者区别在于,发布/订阅模式在观察者模式的基础上,在目标和观察者之间增加一个调度中心。
观察者模式是由具体目标调度,比如当事件触发,
Subject
就会去调用观察者的方法,所以观察者模式的订阅者与发布者之间是存在依赖的。发布/订阅模式由统一调度中心调用,因此发布者和订阅者不需要知道对方的存在。
实现 reduce 方法
初始值不传怎么处理
回调函数的参数有哪些,返回值如何处理。
实现 Array.of 方法
Array.of()
方法用于将一组值,转换为数组
这个方法的主要目的,是弥补数组构造函数
Array()
的不足。因为参数个数的不同,会导致Array()
的行为有差异。Array.of()
基本上可以用来替代Array()
或new Array()
,并且不存在由于参数不同而导致的重载。它的行为非常统一
实现
实现一个 compose 函数
组合多个函数,从右到左,比如:
compose(f, g, h)
最终得到这个结果(...args) => f(g(h(...args))).
题目描述:实现一个 compose
函数
实现代码如下
compose
创建了一个从右向左执行的数据流。如果要实现从左到右的数据流,可以直接更改compose
的部分代码即可实现
更换
Api
接口:把reduce
改为reduceRight
交互包裹位置:把
a(b(...args))
改为b(a(...args))
数组去重方法汇总
首先:我知道多少种去重方式
1. 双层 for 循环
思想: 双重
for
循环是比较笨拙的方法,它实现的原理很简单:先定义一个包含原始数组第一个元素的数组,然后遍历原始数组,将原始数组中的每个元素与新数组中的每个元素进行比对,如果不重复则添加到新数组中,最后返回新数组;因为它的时间复杂度是O(n^2)
,如果数组长度很大,效率会很低
2. Array.filter() 加 indexOf/includes
思想: 利用
indexOf
检测元素在数组中第一次出现的位置是否和元素现在的位置相等,如果不等则说明该元素是重复元素
3. ES6 中的 Set 去重
思想: ES6 提供了新的数据结构 Set,Set 结构的一个特性就是成员值都是唯一的,没有重复的值。
4. reduce 实现对象数组去重复
这种方法是利用高阶函数
reduce
进行去重, 这里只需要注意initialValue
得放一个空数组[],不然没法push
实现 bind 方法
bind
的实现对比其他两个函数略微地复杂了一点,涉及到参数合并(类似函数柯里化),因为bind
需要返回一个函数,需要判断一些边界问题,以下是bind
的实现
bind
返回了一个函数,对于函数来说有两种方式调用,一种是直接调用,一种是通过new
的方式,我们先来说直接调用的方式对于直接调用来说,这里选择了
apply
的方式实现,但是对于参数需要注意以下情况:因为bind
可以实现类似这样的代码f.bind(obj, 1)(2)
,所以我们需要将两边的参数拼接起来最后来说通过
new
的方式,对于new
的情况来说,不会被任何方式改变this
,所以对于这种情况我们需要忽略传入的this
简洁版本
对于普通函数,绑定
this
指向对于构造函数,要保证原函数的原型对象上的属性不能丢失
注意:
bind
之后不能再次修改this
的指向,bind
多次后执行,函数this
还是指向第一次bind
的对象
评论