• 百度前端二面常考手写面试题总结


    将VirtualDom转化为真实DOM结构

    这是当前SPA应用的核心概念之一

    // vnode结构:
    // {
       
    //   tag,
    //   attrs,
    //   children,
    // }
    
    //Virtual DOM => DOM
    function render(vnode, container) {
       
      container.appendChild(_render(vnode));
    }
    function _render(vnode) {
       
      // 如果是数字类型转化为字符串
      if (typeof vnode === 'number') {
       
        vnode = String(vnode);
      }
      // 字符串类型直接就是文本节点
      if (typeof vnode === 'string') {
       
        return document.createTextNode(vnode);
      }
      // 普通DOM
      const dom = document.createElement(vnode.tag);
      if (vnode.attrs) {
       
        // 遍历属性
        Object.keys(vnode.attrs).forEach(key => {
       
          const value = vnode.attrs[key];
          dom.setAttribute(key, value);
        })
      }
      // 子数组进行递归操作
      vnode.children.forEach(child => render(child, dom));
      return dom;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    实现every方法

    Array.prototype.myEvery=function(callback, context = window){
       
        var len=this.length,
            flag=true,
            i = 0;
    
        for(;i < len; i++){
       
          if(!callback.apply(context,[this[i], i , this])){
       
            flag=false;
            break;
          } 
        }
        return flag;
      }
    
    
      // var obj = {num: 1}
      // var aa=arr.myEvery(function(v,index,arr){
       
      //     return v.num>=12;
      // },obj)
      // console.log(aa)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    实现Array.isArray方法

    Array.myIsArray = function(o) {
       
      return Object.prototype.toString.call(Object(o)) === '[object Array]';
    };
    
    console.log(Array.myIsArray([])); // true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    实现数组扁平化flat方法

    题目描述: 实现一个方法使多维数组变成一维数组

    let ary = [1, [2, [3, [4, 5]]], 6];
    let str = JSON.stringify(ary);
    
    • 1
    • 2

    第0种处理:直接的调用

    arr_flat = arr.flat(Infinity);
    
    • 1

    第一种处理

    ary = str.replace(/(\[|\])/g, '').split(',');
    
    • 1

    第二种处理

    str = str.replace(/(\[\]))/g, '');
    str = '[' + str + ']';
    ary = JSON.parse(str);
    
    • 1
    • 2
    • 3

    第三种处理:递归处理

    let result = [];
    let fn = function(ary) {
       
      for(let i = 0; i < ary.length; i++) }{
       
        let item = ary[i];
        if (Array.isArray(ary[i])){
       
          fn(item);
        } else {
       
          result.push(item);
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    第四种处理:用 reduce 实现数组的 flat 方法

    function flatten(ary) {
       
        return ary.reduce((pre, cur) => {
       
            return pre.concat(Array.isArray(cur) ? flatten(cur) : cur);
        }, []);
    }
    let ary = [1, 2, [3, 4], [5, [6, 7]]]
    console.log(flatten(ary))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    第五种处理:能用迭代的思路去实现

    function flatten(arr) {
       
      if (!arr.length) return;
      while (arr.some((item) => Array.isArray(item))) {
       
        arr = [].concat(...arr);
      }
      return arr;
    }
    // console.log(flatten([1, 2, [1, [2, 3, [4, 5, [6]]]]]));
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    第六种处理:扩展运算符

    while (ary.some(Array.isArray)) {
       
      ary = [].concat(...ary);
    }
    
    • 1
    • 2
    • 3
    • 4

    实现节流函数(throttle)

    节流函数原理:指频繁触发事件时,只会在指定的时间段内执行事件回调,即触发事件间隔大于等于指定的时间才会执行回调函数。总结起来就是: 事件,按照一段时间的间隔来进行触发

    像dom的拖拽,如果用消抖的话,就会出现卡顿的感觉,因为只在停止的时候执行了一次,这个时候就应该用节流,在一定时间内多次执行,会流畅很多

    手写简版

    使用时间戳的节流函数会在第一次触发事件时立即执行,以后每过 wait 秒之后才执行一次,并且最后一次触发事件不会被执行

    时间戳方式:

    // func是用户传入需要防抖的函数
    // wait是等待时间
    const throttle = (func, wait = 50) => {
       
      // 上一次执行该函数的时间
      let lastTime = 0
      return function(...args) {
       
        // 当前时间
        let now = +new Date()
        // 将当前时间和上一次执行函数时间对比
        // 如果差值大于设置的等待时间就执行函数
        if (now - lastTime > wait) {
       
          lastTime = now
          func.apply(this, args)
        }
      }
    }
    
    setInterval(
      throttle(() => {
       
        console.log(1)
      }, 500),
      1
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    定时器方式:

    使用定时器的节流函数在第一次触发时不会执行,而是在 delay 秒之后才执行,当最后一次停止触发后,还会再执行一次函数

    function throttle(func, delay){
       
      var timer = null;
      returnfunction(){
       
        
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    【总线】AXI4第四课时:握手机制详解
    《大数据面试通关》(第十四讲)——10 大业务场景 500 个离线实时指标
    华为VRP系统基本操作
    go优雅重试
    数字信号处理——线性相位型(Ⅰ、Ⅲ型)FIR滤波器设计(1)
    [SSM框架]—Spring入门
    让 GPT-4 来 review 开源社区贡献者的 PR - 每天5分钟玩转 GPT 编程系列(5)
    NXP BootLoader源码分析并改写SD卡启动
    Spring IOC中bean的生命周期
    MySQL——进阶
  • 原文地址:https://blog.csdn.net/helloworld1024fd/article/details/127644968