一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第10天,点击查看活动详情。
学习链接
装饰器模式和转发,call/apply (javascript.info)
简介
装饰器 是一个围绕改变函数行为的包装器。主要工作仍由该函数来完成。
改变行为
- 比如,缓存装饰器,原本是计算的函数(行为 - 计算)
- 变成(行为 - 查找),如果就返回,没有就重新计算!
- 是这样理解???
装饰器模式的应用
- 缓存装饰器 - 已计算,返回缓存内容
- 间谍装饰器 - 返回所有对函数的调用 - 单元测试很好!
- 延时装饰器 - 操作延迟。。。
- 防抖装饰器 - 针对操作(点击)!
- 节流装饰器 - 针对频率(滚动加载)!
为什么要介绍装饰器模式?
- 引出call 和apply的场景
- 对象 - 如果给装饰器(函数),是对象中的函数!
- this! - 指向谁? - 需要指定!
call 和apply 的区别
call
这两个区别就是this了。。
func(1, 2, 3);
func.call(obj, 1, 2, 3) - 把this修改为obj!
这是没有传参数的情况,call的第一个参数 - this指向的对象
call 传递一个参数
say.call( user, "Hello" ); // John: Hello
call 传递多个参数
apply
- 和call的作用一样
- 如果需要用到对象中的方法变量等,需要修改this指向
- 唯一和call不同的是传入的参数
call 需要一个参数列表
apply 需要一个包含这些参数的类数组对象 ????
文中提出的方法借用!
[].join.call(arguments)
可以让伪数组,拥有数组的方法!
案例
延时装饰器
- 这里传入的方法是alert!
- 把参数传入arguments
- 箭头函数没有自己的this,this指的f
- 可以替换成
f.call(this, ...arguments), ms);- 注!解构! - 如果不加call, this 指的是 window!
- 如果不加arguments,没有参数!显示为空!
防抖装饰器
面试必备。。。
针对用户操作!
进入 - 先清空,再调用。。。
英文 - debounce
比如:当想要查询的时候,没有必要为每个字符都发送请求,可以等一段时间再发送请求! - 可以把要执行的函数放入 setTimeout中!
测试:
- 如果有很多次调用
- **只执行最后一次!!**前面的都被清空了
节流装饰器
针对频率 - 当多次调用的时候,一段时间内,只调用一次,比如:获取鼠标位置,不用一直获取,可以隔每10 毫秒获取一次!这样就提升了性能!
英文 - throttle
- 防抖 - 不管执行多少次,一定要等到时间才执行
- 节流 - 不管执行多少次,该时间内只执行一次!
代码执行过程!
测试:
- 如果执行很多次
- 第一执行
- 然后到最后一次。。。
用嵌套的setTimeout测试!
- 如果速度和节流的相等 - 可以按setTimeout里面的执行 - 都能执行到
- 如果速度比节流的快 - 只有第一次和最后一次执行!!! - 可以看出节流了!
- 如果比节流的慢,,当然全都执行了,节流的已经修改标志位了!
总结
注:装饰器模式案例中学来的代码,都是返回一个函数,然后使用传入的函数!
为什么要返回函数?????这里不了解。。。。
已经可以默写防抖,和节流了!还有那个嵌套setTimeout,😎!
目前关于防抖和节流的体验:
- 防抖 - 如果速度过快,执行最后一次!
- 节流 - 如果速度过快,执行第一次和最后一次!
- 如果时间相等,都能执行 - 再嵌套setTimout里面
- 如果时间比防抖节流长 - 都能执行 - 再嵌套setTimout里面
- 需要补一下事件循环:微任务和宏任务 (javascript.info)
如果外部调用时间长!
- 节流可以按时间走(外面的)
- 防抖 - 除了第一次,之后按自己的时间走。。
如果没有坚持不懈的重复播种、静谧无言的守望等待,定然不会迎来满山芳华的惊喜