进阶-拓展知识

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有哪些数组去重方法?

【考点映射】

  • 数组去重方法总结、性能分析

【频率】★★★★★(面试极有可能要求撕代码)

【难度】☆☆

  1. 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; 
}
双层循环,外层循环元素,内层循环时比较值,值相同时,删除这个值

    3. for 循环(一次) + indexOf() + 新数组
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%内容,订阅专栏后可继续查看/也可单篇购买

前端岗面试求职真题解析 文章被收录于专栏

前端岗位面试求职攻略及真题解析~~

全部评论

相关推荐

沉淀一会:1.同学你面试评价不错,概率很大,请耐心等待; 2.你的排名比较靠前,不要担心,耐心等待; 3.问题不大,正在审批,不要着急签其他公司,等等我们! 4.预计9月中下旬,安心过节; 5.下周会有结果,请耐心等待下; 6.可能国庆节前后,一有结果我马上通知你; 7.预计10月中旬,再坚持一下; 8.正在走流程,就这两天了; 9.同学,结果我也不知道,你如果查到了也告诉我一声; 10.同学你出线不明朗,建议签其他公司保底! 11.同学你找了哪些公司,我也在找工作。
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务