进阶-拓展知识
4 进阶-拓展知识
4.1 请问什么是函数防抖?什么是函数节流?
【考点映射】
-
防抖与节流概念、区别
-
防抖与节流实现
【频率】★★★★★(面试极有可能要求撕代码)
【难度】☆☆
【参考答案】
函数防抖(debounce):触发高频事件后n秒内,函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间
函数节流(throttle):高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率
两者都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象
防抖:
实现思路:在事件被触发n秒后再执行回调函数,如果在这n秒内又被触发,则重新计时
特点:如果事件在规定的时间间隔内被不断的触发,则调用方***被不断的延迟,当遇到不断触发但是仍然需要触发的情况,应该选用节流
只有当高频事件停止,最后一次事件触发的超时调用才能在wait时间后执行
function debounce(func, wait) { var timeout; // 用来存放定时器的返回值,一触发就重新计时 return function () { var context = this; // 把前一个 setTimeout clear 掉 clearTimeout(timeout) // 又创建一个新的 setTimeout, 保证间隔内时间持续触发,不会执行func函数 timeout = setTimeout(function(){ func.apply(context) }, wait); } }
节流:(每隔一段时间发一次 Ajax 请求,用节流)
规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效
实现思路:通过判断是否到达一定时间来触发函数,若没到规定时间则使用计时器延后,而下一次事件则会重新设定计时器
function throttle(fn,delay) { let canRun = true; // 通过闭包保存一个标记 return function () { // 在函数开头判断标记是否为true,不为true则return if (!canRun) return; // 立即设置为false canRun = false; // 将外部传入的函数的执行放在setTimeout中 setTimeout(() => { // 最后在setTimeout执行完毕后再把标记设置为true(关键)表示可以执行下一次循环了。 // 当定时器没有执行的时候标记永远是false,在开头被return掉 fn.apply(this, arguments); canRun = true; }, delay); }; }
4.2 请问js有哪些数组去重方法?
【考点映射】
-
数组去重方法总结、性能分析
【频率】★★★★★(面试极有可能要求撕代码)
【难度】☆☆
-
for循环(两次嵌套)+ 新数组
function sort(arr) { var flag = 0; var result = new Array(); for(var i = 0; i < arr.length; i++) { flag = 0; for(var j = 0; j < arr.length; j++) { if(result[j] == arr[i]) { flag = 1; break; } } if(flag == 0) result.push(arr[i]); } return result; }
新建一个空数组,for循环遍历原数组,判断数组内是否已存在当前元素,如有相同的值则跳过,不同的推入新数组中,直至原数组遍历完,返回新数组,涉及到多次遍历,执行时间较长
2. for循环(两次嵌套)+ splice (ES5中最常用)
function sort(arr){ for(var i=0; i<arr.length; i++){ for(var j=i+1; j<arr.length; j++){ if(arr[i]==arr[j]){ //两者相等时,splice方法删除第二个 arr.splice(j,1); j--; } } } return arr; }
function sort(arr) { var result = new Array(); for(var i = 0; i < arr.length; i++) { if(result.indexOf(arr[i]) == -1) result.push(arr[i]); } return result; }
对方法1进行改进,对新数组判定是否有该字符,可以调用 Array.prototype.indexOf 函数,执行时间缩减了很多
4. sort()
function sort(arr) { arr = arr.sort() var result= [arr[0]]; for (var i = 1; i < arr.length; i++) { if (arr[i] !== arr[i-1]) { result.push(arr[i]); } } return result; }
利用sort()排序方法,然后根据排序后的结果进行遍历及相邻元素对比
5. Map
function sort(arr) { let map = new Map(); let result = new Array(); for (let i = 0; i < arr.length; i++) { if(map.has(arr[i])) { // 如果有该key值 map.set(arr[i], true); } else { map.set(arr[i], false); // 如果没有该key值 result.push(arr[i]); } } return result ; }
利用 ES6 中的 Map 集合替代前面方法中的新数组,调用Map.has替代indexOf(),Map.set 替代push(),执行速度比前面的方法都要快
6. new Set() + Array.from()
function sort(arr) { return Array.from(new Set(arr)); }
利用 ES6 中的 Set 集合,Set 集合是一种无重复元素的列表,new Set(arr
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
前端岗位面试求职攻略及真题解析~~