大厂面试题集合-每日一题

每日一题,巩固基础
自己做一遍,写上自己的解法和做题时遗忘的知识点
这样不仅能巩固知识,写上自己的想法也方便以后查阅和复习

题目来源: https://github.com/Advanced-Frontend/Daily-Interview-Question

第1题-2019/3/24

  • 题目
['1', '2', '3'].map(parseInt)  

答案: [1,NaN,NaN]
  • 复习

parseInt(string, radix) // string表示被解析的字符串,radix按照什么进制来解析
  • 分析
['1','2','3'].map(parseInt)
// 等价于下面
['1','2','3'].map((val,index) => parseInt(val,index))

* 步骤
// parseInt(‘1’,0),按照10进制解析,返回1
// parseInt(‘2’,1),按照1进制解析,但是被解析字符串为2大于1进制的最大数1所以返回NaN
// parseInt(‘3’,2),   同上返回NaN

第2题-2019/3/25

防抖函数与节流函数的区别?

防抖函数

比如一个请求按钮,你快速点击多次,如果没有防抖函数就会发出多次请求,浪费带宽和性能,有了防抖函数,快速点击多次我也只发送最后一次的点击请求

简单版防抖函数
var inp = document.getElementById('inp');
inp.addEventListener('input', debounce(sayHi)); // 防抖
  • Es6写法,绑定this
const debounce = (fn,wait) => {
    let timer = null //存放定时器的返回值
    return function(...args){
        // 如果await期间点击多次,清除前面触发的,只执行最后一次
        if(timer) clearTimeout(timer) 
        timer = setTimeout(() => { //注意这里Es6写法和Es5写法有区别
            // 绑定this,确保上下文执行环境
            fn.apply(this,args) 
        },wait)
    }
}
function sayHi() {
    console.log(this) //<input type="text" id="inp">
}
  • Es5写法,绑定this

const debounce = (fn,wait) => {
    let timer = null 
    return function(...args){
        if(timer) clearTimeout(timer) 
        timer = setTimeout(function(){ //Es5写法
            fn.apply(this,args) 
        },wait)
    }
}
function sayHi() {
    console.log(this) // window 
    // 因为Es6写法有块级作用域,函数的this在生成时就已经确定了
    // Es5没有块级作用域,this在函数执行的时候,由其上下文执行环境确定
}
  • Es6写法不绑定this
const debounce = (fn,wait) => {
    let timer = null 
    return function(...args){
        if(timer) clearTimeout(timer) 
        timer = setTimeout(() => { 
            // 不绑定this,确保上下文执行环境
            fn.apply() 
        },wait)
    }
}
function sayHi() {
    console.log(this) //window
}

延迟函数高级版

根据传入的参数决定是否立即执行,还是延迟执行
立即执行: 输入一个字符就发送一次请求
延迟执行: 输入下一个字符时间小于设定的wait时间,那么就清理上一次触发的事件,执行当前触发的事件

function debounce(fn,wait,immediate){
  let context, context, timer

  //延迟执行函数
  const later = () => setTimeout(() => {
    // 延迟函数执行完毕,清空缓存的定时器序号
    timer = null
    if(!immediate){
      fn.apply(context,args)
      // 闭包函数使用后的变量不会被清理,手动清理防止内存泄漏
      context = args = null
    }
  })

  return function(...params){
    if(!timer){
      // 如果没有创建延迟执行函数(later),就创建一个
      timer = later()
      if(immediate){ 
        // 立即执行,不用setTimeout
        fn.apply(this,params)
      }else{
        context = this
        args = params
      }
    }else{
      clearTimeout(timer)
      //取消上一个,执行下一个
      timer = later()
    }
  }
}


节流函数

防抖动是将多次执行变成执行最后一次,节流是将多次执行,变成每隔一段时间执行

function throttle(fn,wait){
    let flag = true // 通过闭包保存一个标记
    return function(){
        if(!flag) return
        // 设置falg为false,本次事件没执行完,如果又发生调用,上面flag就会return 
        // 所以不会再触发一个事件
        flag = false
        setTimeout(() => {
            fn.apply(this,arguments)
            // 设置flag为turn表示本次事件执行完了,可以执行下一次的
            flag = true
        })
    }
}

导致节流和防抖函数的细微区别是因为闭包,这里顺便复习下闭包

function fa() {
    var a = 1;
    return function () {
        console.log(a)
        a++
    }
}
var o = fa();
o(); // 1
o(); // 2

参考文章: https://www.cnblogs.com/blowfish/p/3323357.html
https://www.cnblogs.com/yakun/p/3932026.html

猜你喜欢

转载自blog.csdn.net/qq1498982270/article/details/88675134