JS的防抖,节流,柯里化和反柯里化
节流
定义
将高频率事件转变为低频率事件
实现
- 定时器实现
- 时间戳实现
定时器实现
实现思路:当触发事件的时候,我们设置一个定时器,再次触发事件的时候,如果定时器存在,就不执行,直到delay时间后,定时器执行执行函数,并且清空定时器,这样就可以设置下个定时器。当第一次触发事件时,不会立即执行函数,而是在delay秒后才执行。而后再怎么频繁触发事件,也都是每delay时间才执行一次。当最后一次停止触发后,由于定时器的delay延迟,还会执行一次函数。
var throttle = function(func, delay) { var timer = null; return function() { var context = this; var args = arguments; if (!timer) { timer = setTimeout(function() { func.apply(context, args); timer = null; }, delay); } } }
时间戳实现
实现思路:使用事件戳来计算时间,时间差大于delay则执行
var throttle = function(func, delay) { var prev = Date.now(); return function() { var context = this; var args = arguments; var now = Date.now(); if (now - prev >= delay) { func.apply(context, args); prev = Date.now(); } } }
应用场景
- 鼠标不断点击触发,mousedown(单位时间内只触发一次)
- 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断
防抖
定义
将高频事件只在最后一次进行触发。即不关心中间过程,只注重结果
实现
实现思路:利用定时器,触发时不停清空上一个定时器,只有当不触发时才会执行函数fn
function debounce(fn, wait) { var timeout = null; return function() { if(timeout !== null) clearTimeout(timeout); timeout = setTimeout(fn, wait); } }
应用场景
- search输入框,在输入完之后请求接口
- 页面滚动特定距离 显示【返回顶部按钮】
- 页面resize 触发事件
柯里化
定义
是柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。
特性
- 提高了代码的合理性,更重的它突出一种思想---降低适用范围,提高适用性。
- 对于一个已有函数,对其约定好其中的某些参数输入,然后生成一个更有好的、更符合业务逻辑的函数。
- 提高针对性
- 延迟执行(只有在最后一次才执行)
- 固定易变因素
实现
实现思路:利用闭包,只要由参数就保存参数,并返回函数,无参数时则执行
function add() { //建立args,利用闭包特性,不断保存arguments,注意arguments是个对象 // 注意JS中的Array.prototype.slice.call(arguments)能将有length属性的对象转换为数组(特别注意: 这个对象一定要有length属性). var args = Array.prototype.slice.call(arguments); var _add = function() { if (arguments.length === 0){ //参数为空,对args执行加法 return args.reduce(function(a,b){return a+b}); } else { //否则,保存参数到args,返回一个函数 args = args.concat(Array.prototype.slice.call(arguments)) return _add; } } //返回_add函数 return _add; }
反柯里化
定义
在与扩大函数的适用性,使本来作为特定对象所拥有的功能的函数可以被任意对象所用.简单来说就是函数的借用,使函数能够接受处理其他对象,通过借用泛化、扩大了函数的使用范围。
实现
Function.prototype.uncurrying = function() { var self = this; return function() { var obj = Array.prototype.shift.call(arguments); return self.apply(obj, arguments); }; };
更简便的写法
Function.prototype.uncurrying = function() { var self = this; return function() { return Function.prototype.call.apply(self,arguments) }; }
参考
https://www.cnblogs.com/dupd/p/8449711.html
https://blog.csdn.net/weixin_34341229/article/details/88216754
语雀链接🔗 https://www.yuque.com/suihangadam
归来卧占楼千尺,梦落沧波明月舟。