距离上次学习clone函数已经好几周了,由于我现在的理念是尽可能的能坚持长期学习,所以我给自己的任务没有很重,会更倾向于轻松一点,但是可能前两周有点太宽松了,就没有花时间在学习上。这两天又慢慢的把自己的状态调整回来,然后我又回到了debounce函数。
这个函数我目前已经看了很多遍了,我感觉基本上每一行我都能理解它的用意,我觉得这个过程是有趣的。
在分析的过程中,我学到了一个方法,那就是脑子里有一个作用域,你要记得代码跑到某个地方的时候,你有哪些变量可以用,因为除了关键字,能出现的就是这些变量,我觉得这样会有一个大局观吧,就是你会记得这个变量,记得它是在哪里声明的,它用了几次(它的用处)。还有一个好处就是,在代码正常执行完毕后,如果你知道此时还有哪些变量,那么你也能更好的去重置变量的状态,使你不那么容易忽略它。
虽然只是一个小小的debounce函数,我觉得在我工作了几年之后,读了这样的代码之后我还是会有很多收获,有可能是自己基础太差了,也有可能工作上追求的是效率,自己根本没有花时间在编码上,心态上会比较随意,然后出现问题了就一顿乱改,到最后能运行就行。不过工作确实比较特殊,可能真的没那么多时间让我来思考这些,所以更多的还是需要自主驱动,通过阅读一些好的代码,熟悉一些好的写法,把它带到工作当中,这样会更好。
下面的代码是我读了just的源码后自己写的,不过我觉得我也只是记住了这种写法,或许还没有真正的理解 因为在阅读了别人的代码之后,你写出来的代码多多少少会带点别人的影子,不过我觉得应该许多人都要经历这种过程吧,当你肚子里没有墨水的时候,你只能先模仿别人的东西,慢慢理解变成自己的东西,等你掌握的足够多之后,才能输出真正属于自己的东西。
接下来我描述一下我在写这个函数时的心理活动吧
首先我觉得写好一个函数,我需要知道这个函数的功能
比如这是一个防抖函数,要有正常的防抖功能,通过外部取消定时器,通过外部立马执行
然后我会思考它的参数和返回值
比如接收一个函数,延时时间,是否需要首次执行。
返回值则是一个函数
内部细节及其它
其他的内部细节我觉得我还讲不出来,功力应该还不够,我还没有真正的理解它,我只是能够模仿它
function debounce(fn, wait, callFirst) {
let timeout = null
let debouncedFn = null
// flush需要调用
// 1.清除定时器
// 2.直接调用debounce函数,并且需要重置该函数
//
// 重新开始定时任务前需要调用
// 1.清除定时器, timeout重置为null
// 2.debounce函数重置为null
// 外部取消定时器时需要调用
// 和flush大致相同
const clear = function () {
if (timeout) {
clearTimeout(timeout)
timeout = null
debouncedFn = null
}
}
// 获取防抖函数
// 调用clar
// 执行防抖函数
const flush = function () {
const fn = debouncedFn
clear()
if (fn) {
fn()
}
}
const wrapper = function (...args) {
// 直接调用
// wait为各种False值时
if (!wait) {
return fn.apply(this, args)
}
// 定时调用
// 分为两种情况
// 是否需要立马调用一次
const callNow = !timeout && callFirst
const context = this
clear()
debouncedFn = function () {
return fn.apply(context, args)
}
timeout = setTimeout(() => {
timeout = null
if (!callNow) {
const call = debouncedFn
debouncedFn = null
return call()
}
}, wait);
if (callNow) {
return debouncedFn()
}
}
wrapper.cancel = clear
wrapper.flush = flush
return wrapper
}
下一个函数我会去学习just中的pick函数,也就是从对象中取出对应的key变成一个新对象