以下题目来自掘金等其它博客,但是问题的答案都是根据笔者自己的理解做出的。如果你最近想要换工作或者巩固一下自己的前端知识基础,不妨和我一起参与到每日刷题的过程中来,如何?
第jiu天要刷的手写题如下:
- 实现斐波那契数列
- 使用定时器实现setInterval函数功能
- 间隔一秒打印1-5
下面是我自己写的答案:
1. 间隔一秒打印1-5
1.1 递归版本
js
function fi(n) {
if(n===0 || n===1) return 1;
return fi(n-1)+fi(n-2);
}
1.2 缓存版本
js
const cache = {
0: 1,
1: 1,
}
function fi(n) {
if (cache[n]) return cache[n];
cache[n] = fi(n - 1) + fi(n - 2);
return cache[n];
}
1.3 使用闭包
js
const fi = (function (n) {
const cache = {
0: 1,
1: 1,
}
return function fi(n) {
if (cache[n]) return cache[n];
cache[n] = fi(n - 1) + fi(n - 2);
return cache[n];
}
})()
1.4 使用迭代代替递归
js
const cache = [1, 1];
function fi(n) {
for(let i = 2; i<=n; i++){
cache[i] = cache[i-1]+cache[i-2];
}
return cache[n];
}
1.5迭代和缓存
js
const cache = [1, 1];
function fi(n) {
if(cache[n]) return cache[n];
const startIndex = cache.length;
for(let i = startIndex; i<=n; i++){
cache[i] = cache[i-1]+cache[i-2];
}
return cache[n];
}
2. 使用定时器实现间隔器
本质上是封装了业务的函数和封装了定时器的函数之间的相互调用,outer函数的返回值需要提供使之停下来的方法。
js
function myInterval (exec, gap) {
let timer = null;
// 封装业务的函数
const _exec = () => {
exec();
_loop();
}
// 封装定时器的函数
function _loop(){
timer = setTimeout(
_exec, gap
)
}
// 开始执行
_loop();
// 返回使循环停止的方法
return function _stop () {
clearTimeout(timer);
}
}
const stop = myInterval(()=>console.log(+new Date()), 1000);
3. 间隔一秒打印1-5
此问题需要拆分一下,很容易下意识的认为先打印1,隔一秒之后打印2,再隔一秒打印3... 但是程序执行是需要时间的,正确的做法应该是,第一秒打印1,第二秒打印2...
js
function print15(){
const _start = +new Date();
for(let i = 1; i <= 5; i++){
setTimeout(
()=>{
console.log(i);
console.log(+new Date()-_start);
}, i*1000
)
}
}