这是我参与「第四届青训营 」笔记创作活动的的第4天
1. 组件封装
三次重构:
-
插件化
-
模板化
-
抽象化(组件框架)
- 改进空间: 是否可以父子插件分离等
2. 过程抽象
普遍应用在框架上,如react boost
常用高阶函数
1.单次执行 (once)
在页面中有一按钮,要求为其添加事件监听器:当这个按钮被点击时,
- 在控制台打印 "hello world!" ;
- 并要求这个动作只执行一次,若之后按钮再次被点击,打印动作也不会执行。
我们通常使用的方法是 addEventListener,并且在可选参数options中将 once 设置为 true ,意为只执行一次。
const btn = document.getElementById('btn');
document.addEventListener('click',()=>{
console.log('hello world!');
},{once:true});
2.节流 (throttle)
以页面中的按钮为例子,我希望用户在点击这个按钮时,
- 控制台中会打印 "hello world!" ;
- 为按钮发挥作用添加冷却时间,如500ms。
这意味着 addEventListener 绑定的函数在执行一次后会进入500ms的冷却时间,当这一冷却时间结束后,点击按钮才能产生打印"hello world!"的效果;但下一次打印操作完成后,按钮又会再次进入冷却。
在冷却过程中,无论用户点击多少次按钮,都不会有打印的操作。
这样的限制条件称为节流(throttle) 。下面是一个针对节流的高阶函数:
function throttle(fn,time = 500){
let timer;
return function(...args){
if(timer == null){
fn.apply(this,args);
timer = setTimeout(()=>{
timer = null;
},time);
}
}
}
对于使用高阶函数throttle()生成新函数时,传入的参数除了包含被调用的回调函数外,还需要传入一个间隔的时间time,回调函数的执行便以time为时间间隔。具体时间可由使用者指定。
3.防抖 (debounce)
页面上存在一个内容被监听的多行输入框,对于这一输入框:
- 当输入框中的内容发生变化时,控制台实时打印输入框中的内容;
- 但必须在用户无输入操作500ms后,才允许进行打印操作。
如果不添加 “用户无输入操作若干秒后才打印” 的限制条件,当输入框的内容稍有变化时,控制台便会马上打印;当内容变化的次数一多,控制台打印操作便会变得频繁,产生抖动。
对于一些不希望产生抖动的操作,则需要添加限制条件,称为 防抖(debounce) 。下面是一个针对防抖的高阶函数:
function debounce(fn,dur = 500){
let timer;
return function(...args){
clearTimeout(timer);
timer = setTimeout(()=>{
fn.apply(this,args);
},dur);
}
}
参数dur为等待无操作所持续(duration)的时间。
每次在执行debounce()返回的新函数前,都要使用clearTimeout()方法取消setTimeout()的定时,即打断当前的等待间隔时间和执行规律,随后再重新设置一个定时器。
在新设置的定时器中,以dur为时间间隔执行回调函数。
为什么要使用高阶函数?
纯函数与非纯函数
纯函数 (pure function)
- 对外部没有副作用
- 效果可预期
非纯函数 (inpure function)
- 对外部有副作用
- 测试时要构造特定的环境、初始化和还原
- 测试难度更大
| 非纯函数越多,可维护性就越差,所以尽量使用纯函数。 |
使用高阶函数的好处
- 过程抽象
- 高阶函数都是纯函数,效果可预期
- 提升代码的可维护性