进阶-拓展知识
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%内容,订阅专栏后可继续查看/也可单篇购买
前端岗位面试求职攻略及真题解析~~
查看29道真题和解析
