前端面试手写题系列 IV
前端面试 手写题系列 已经完结,包含了以下的题目:
手写拍平数组 flat 手写防抖和节流函数 手写深拷贝 手写快排 手写 call、apply、bind 手写一个 sleep 函数 手写冒泡排序 函数柯里化 对象扁平化 手写 new 过程 求数组中的最大值 手写 instanceof 手写 foreach 函数 手写迭代器 手写 filter 实现一个 compose 函数 正则相关(去哪儿原题) 实现一个任务调度函数(得物原题) 数组转化为 tree 不使用 a 标签,实现 a 标签的功能 手写插入排序 LRU 算法 归并排序 求两个数组的交集、并集、补集、差集 提取 url 中的参数 实现一个洗牌函数 shuffle 希尔排序
1.实现一个 compose 函数
目的:
compose 函数的目的是组合多个函数:
实现:
<script>
// 用法如下:
function fn1(x) {
return x + 1;
}
function fn2(x) {
return x + 2;
}
function fn3(x) {
return x * 3;
}
// 我们原来的写法就是 fn3(fn2(fn1(1)))
// 但是这里我们可以用 compose 函数来实现
const a = compose(fn1, fn2, fn3);
console.log(a(1)); // 7
// compose 函数的实现
function compose(...fns) {
return function (x) {
return fns.reduce((acc, fn) => {
return fn(acc);
}, x);
};
}
</script>
2.正则相关(去哪儿原题)
像这种正则表达式,一般我们感觉都是不会考察的,但是实际上就是考了。
下面依次为
- 是否是电话号码
- 是否是邮箱 -> 我当时考察的就是邮箱,没写出来
- 是否是身份证号码
function isPhone(tel) {
var regx = /^1[345789]\d{9}$/;
return regx.test(tel);
}
function isEmail(email) {
var regx = /^[A-Za-z0-9]+([_\.][A-Za-z0-9]+)*@([A-Za-z0-9\-]+\.)+[A-Za-z]{2,6}$/;
return regx.test(email);
}
function isCardNo(number) {
var regx = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
return regx.test(number);
}
使用场景:
如果真的能记住或者自己能够写出来的话,正则真的是一把利剑,很多自己无法实现或者实现不全的判断函数,都只需要一个正则表达式就可以解决。
3.实现一个任务调度函数(得物原题)
目的:
实现这么一个函数,可以按照以下的顺序调度执行任务:
arrange('William').wait(5).do('commit').execute()
意思其实很明显,传入一个参数 William,然后等五秒,然后执行 do,然后执行 execute
实现:
// 关键就在于一个任务队列,每个任务都是一个函数,然后顺序执行就好了
// 等待的话,就是在任务队列中添加一个等待函数,等待函数返回一个promise,等待时间到了,就resolve
// 为什么只有在promise成功之后,才会执行下一个任务呢?因为await只有在promise成功之后,才会执行下一个任务
function arrange(str) {
return new Arrange(str)
}
class Arrange {
constructor(str) {
this.str = str
// 一个任务队列
this.tasks = []
// 先执行一次
this.tasks.push(() => console.log(`${this.str} is notified`))
}
// 执行任务队列, 顺序执行
async execute() {
for (let i of this.tasks) {
await i()
}
}
// 添加任务
do(action) {
this.tasks.push(() => {
console.log(`start do ${action}`)
})
return this
}
// 等待函数,同时返回this,方便链式调用
wait(time) {
this.tasks.push(
() =>
new Promise(resolve => {
console.log(`等待 ${time} 秒`)
setTimeout(() => {
resolve()
}, time * 1000)
})
)
return this
}
}
// 测试
arrange('William').wait(5).do('commit').execute()
手写题系列文章
前端手写题系列 I
前端手写题系列 II
前端手写题系列 III
前端手写题系列 IV
前端手写题系列 V
前端手写题系列 VI
前端手写题系列 VII
前端手写题系列 VIII
前端手写题系列 IX
前端手写题系列 X