本系列最开始是为了本身面试准备的.后来发现整理愈来愈多,差很少有十二万字符,最后决定仍是分享出来给你们.前端
为了分享整理出来,花费了本身大量的时间,起码是只本身用的三倍时间.若是喜欢的话,欢迎收藏,关注我!谢谢!vue
前端面试查漏补缺--Index篇(12万字符合集) 包含目前已写好的系列其余十几篇文章.后续新增值文章不会再在每篇添加连接,强烈建议议点赞,关注合集篇!!!!,谢谢!~面试
后续还会继续添加设计模式,前端工程化,项目流程,部署,闭环,vue常考知识点 等内容.若是以为内容不错的话欢迎收藏,关注我!谢谢!算法
目前本人也在准备跳槽,但愿各位大佬和HR小姐姐能够内推一份靠谱的武汉 前端岗位!邮箱:bupabuku@foxmail.com.谢谢啦!~设计模式
相同:在不影响客户体验的前提下,将频繁的回调函数,进行次数缩减.避免大量计算致使的页面卡顿.前端工程化
不一样:防抖是将屡次执行变为最后一次执行,节流是将屡次执行变为在规定时间内只执行一次.跨域
指触发事件后在规定时间内回调函数只能执行一次,若是在规定时间内又触发了该事件,则会从新开始算规定时间。浏览器
网上有这个比喻:函数防抖就是法师发技能的时候要读条,技能读条没完再按技能就会刷新技能,从新进行读条。缓存
四个字总结就是 延时执行闭包
两个条件:
1,若是客户连续的操做会致使频繁的事件回调(可能引发页面卡顿).
2,客户只关心"最后一次"操做(也能够理解为中止连续操做后)所返回的结果.
例如:
经过定时器将回调函数进行延时.若是在规定时间内继续回调,发现存在以前的定时器,则将该定时器清除,并从新设置定时器.这里有个细节,就是后面全部的回调函数都要能访问到以前设置的定时器,这时就须要用到闭包(详见后面提到的)
防抖分为两种:
//非当即执行版: //首先准备咱们要使用的回调函数 function shotCat (content) { console.log('shotCat出品,必属精品!必须点赞!(滑稽)') } //而后准备包装函数: //1,保存定时器标识 //2,返回闭包函数: 1)对定时器的判断清除;2)通常还须要保存函数的参数(通常就是事件返回的对象)和上下文(定时器存在this隐式丢失,详情能够看我不知道的js上) //最后补充一句,这里不建议经过定义一个全局变量来替代闭包保存定时器标识. function debounce(fun, delay = 500) { //let timer = null 保存定时器 return function (args) { let that = this let _args = args //这里对定时器的设置有两种方法,第一种就是将定时器保存在函数(函数也是对象)的属性上, //这种写法,很简便,但不是很经常使用 clearTimeout(fun.timer) fun.timer = setTimeout(function () { fun.call(that, _args) }, delay) //另一种写法就是咱们比较常见的 //if (timer) clearTimeout(timer); 相比上面的方法,这里多一个判断 //timer = setTimeout(function () { // fun.call(that, _args) //}, delay) } } //接着用变量保存保存 debounce 返回的带有延时功能的函数 let debounceShotCat = debounce(shotCat, 500) //最后添加事件监听 回调debounceShotCat 并传入事件返回的对象 let input = document.getElementById('debounce') input.addEventListener('keyup', function (e) { debounceShotCat(e.target.value) }) //带有当即执行选项的防抖函数: //思路和上面的大体相同,若是是当即执行,则定时器中再也不包含回调函数,而是在回调函数执行后,仅起到延时和重置定时器标识的做用 function debounce(fun, delay = 500,immediate = true) { let timer = null //保存定时器 return function (args) { let that = this let _args = args if (timer) clearTimeout(timer); //不论是否当即执行都须要首先清空定时器 if (immediate) { if ( !timer) fun.apply(that, _args) //若是定时器不存在,则说明延时已过,能够当即执行函数 //无论上一个延时是否完成,都须要重置定时器 timer = setTimeout(function(){ timer = null; //到时间后,定时器自动设为null,不只方便判判定时器状态还能避免内存泄露 }, delay) } else { //若是是非当即执行版,则从新设定定时器,并将回调函数放入其中 timer = setTimeout(function(){ fun.call(that, _args) }, delay); } } }
当持续触发事件时,在规定时间段内只能调用一次回调函数。若是在规定时间内又触发了该事件,则什么也不作,也不会重置定时器.
防抖是将屡次执行变为最后一次执行,节流是将屡次执行变为在规定时间内只执行一次.通常不会重置定时器. 即不会if (timer) clearTimeout(timer);
(时间戳+定时器版除外)
两个条件:
1,客户连续频繁地触发事件
2,客户再也不只关心"最后一次"操做后的结果反馈.而是在操做过程当中持续的反馈.
例如:
注意 :何为连续频繁地触发事件,就是事件触发的时间间隔至少是要比规定的时间要短.
节流有两种实现方式
//时间戳版: //这里fun指的就是回调函数,我就不写出来了 function throttle(fun, delay = 500) { let previous = 0; //记录上一次触发的时间戳.这里初始设为0,是为了确保第一次触发产生回调 return function(args) { let now = Date.now(); //记录此刻触发时的时间戳 let that = this; let _args = args; if (now - previous > delay) { //若是时间差大于规定时间,则触发 fun.apply(that, _args); previous = now; } } } //定时器版: function throttle(fun, delay = 500) { let timer; return function(args) { let that = this; let _args = args; if (!timer) { //若是定时器不存在,则设置新的定时器,到时后,才执行回调,并将定时器设为null timer = setTimeout(function(){ timer = null; fun.apply(that, _args) }, delay) } } } //时间戳+定时器版: 实现第一次触发能够当即响应,结束触发后也能有响应 (该版才是最符合实际工做需求) //该版主体思路仍是时间戳版,定时器的做用仅仅是执行最后一次回调 function throttle(fun, delay = 500) { let timer = null; let previous = 0; return function(args) { let now = Date.now(); let remaining = delay - (now - previous); //距离规定时间,还剩多少时间 let that = this; let _args = args; clearTimeout(timer); //清除以前设置的定时器 if (remaining <= 0) { fun.apply(that, _args); previous = Date.now(); } else { timer = setTimeout(function(){ fun.apply(that, _args) }, remaining); //由于上面添加的clearTimeout.实际这个定时器只有最后一次才会执行 } } }
做者:shotCat连接:https://juejin.im/post/5c6bab91f265da2dd94c9f9e来源:掘金著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。