每日前端手写题--day2
第二天要刷的手写题如下:
- 手写一个函数,实现节流。
- 手写一个函数,实现防抖。
- 手写一个函数,实现简单浅拷贝。
下面是我自己写的答案:
1. 手写一个函数,实现节流
首先,节流的含义可以简单地理解成:在规定的时间内同一个函数不可以被触发超过一次。那么从其实现的功能出发,可以推出实现的策略为:
- 建立一个闭包,在闭包中存储函数最后一次执行成功的时间戳
lastExeTime
; - 然后在每一次尝试性执行此函数的额时候,获取当前的时间戳
currentTime
,并与最后一次执行成功的时间戳做差const gap = currentTime - lastExeTime
; - 如果gap的值大于规定值,则证明无需节流,执行函数,然后更新
lastExeTime
的值; - 如果gap的值小于规定值,则证明还在节流,这个时候什么都不需要做。
function throttle (fn, wait) {
let lastExeTime = 0;
return function (...args) {
const currentTime = +new Date();
const gap = currentTime - lastExeTime;
if(gap > wait){
lastExeTime = currentTime;
fn.apply(this, args);
}
}
}
2. 手写一个函数,实现防抖
首先,防抖的含义可以简单地理解成:在函数触发之前必须连续的等待规定的时间。这里需要重点理解连续的等待,所谓等待就是指规定的时间之后执行,而连续指的是在等待的过程中不能尝试去触发此函数,如果尝试了就打破了连续性,就需要重新计时。那么从其实现的功能出发,可以推出实现的策略为:
- 建立一个闭包,在其中使用一个变量
timer
表示当前状态; - 如果timer的值为undefined,表示此函数从来没有执行过;
- 如果timer的值为null,表示此刻无需防抖;
- 如果timer的值为设置定时器的返回值,则表示此时需要防抖;
- 根据timer的状态,引导待执行的函数做出不同的反应。
function debounce (fn, delay) {
let timer = undefined;
return function (...args) {
if (!timer) {
clearTimeout(timer);
}
timer = setTimeout(
() => {
timer = null;
fn.apply(this. args);
}, delay
);
}
}
可能你会觉得上面的实现过程中有一些代码是多余的;但是你先不要着急,因为按照最开始的策略就是应该这样实现。
接下来,加强上面的节流函数,加强的结果就是,使用者可以选择在fn执行之前连续等待规定的时间,或者先执行,然后再连续等待规定的时间;有一点不会变,那就是在连续等待的这段时间内需要防抖。
使用另外的语义化的参数immediate
来表示使用者选择了哪种模式。
function debounce (fn, delay, immediate) {
let timer = undefined;
return function (...args) {
if (!timer) {
clearTimeout(timer);
}
if (!timer && immediate) {
fn.apply(this. args);
}
timer = setTimeout(
() => {
timer = null;
if(!immediate) fn.apply(this. args);
}, delay
);
}
}
注意!两个判断条件分别是if (!timer && immediate)
和if(!immediate)
,是不一样的!
3. 手写一个函数,实现简单浅拷贝
这个题要想做的好,首先必须画好边界:
- 只拷贝对象类型,其他基本类型直接照原样输出;
- 简单的浅拷贝只需要区分数组和一般值对象,不要去管其他类型的对象;
- 只对目标对象上的ownProperty进行拷贝,而不要管原型链上的属性;
据此,实现的程序如下:
function shallowCopy (source) {
if( Object(source) !== source ) return source;
const _tmp = Array.isArray(source) ? [] : {};
for (let key in source) {
if (source.hasOwnProperty(key)) _tmp[key] = source[key];
}
return _tmp;
}
补充一个知识点,如果a是"object"类型的,如何判断a的b属性的值是否是真的undefined?
() => a.b === undefined && a.hasOwnProperty(b)
转载自:https://juejin.cn/post/7282975291000291340