前端手写笔试题

1.多维数组转为一维数组

let firstArr = [1, [2, [[3, 4], 5], 6]]

1.1 使用递归

思路:循环数组每一项,如果是数组类型,则递归,否则,放到新数组里


    let finalArr = []

    function deepArr(a) {
    
    

      for (let i = 0; i < a.length; i++) {
    
    
        if (Array.isArray(a[i])) {
    
    
          deepArr(a[i])
        } else {
    
    
          finalArr.push(a[i])
        }
      }
    }
    deepArr(firstArr)
    console.log(finalArr)

1.2 使用数组reduce方法

数组 reduce 方法,包含四个参数:

  • perviousValue:上一次的计算结果的返回值
  • currentValue:数组中正在处理的元素。若指定了初始值,则值则为数组索引为 0 的元素,否则为 1
  • currentIndex:数组中正在处理的元素的索引。若指定了初始值,则起始索引为 0,否则为 1
  • array:被遍历的对象数组

initialValue(可选):此参数作为第一次调用函数时参数 previousValue 的值,
若指定了初始值 initialValue,则 currentValue 则将使用数组第一个元素;
否则 perviousValue 将使用数组的第一个元素,而 currentValue 将使用数组第二个元素

 const flatten = arr => arr.reduce(
      (acc, val) => acc.concat(Array.isArray(val) ? flatten(val) : val), []
    )
    console.log(flatten(arr))

1.3 使用join,split

思路:将数组转换为字符串,再转换回来
问题:转换之后元素都为字符串类型

 let finalArr=arr.join(',').split(',')
    console.log(finalArr)

1.4 使用apply

问题:只能将二维数组改为一维

const arr = [1,[2,3],[4,5]];
console.log([].concat.apply([],arr));

2 数组去重

let arr=[11,22,33,44,55,66,77,88,33,22,44,11]

2.1 使用es6新增的set集合

let final=new Set(arr)

2.2 利用indexOf只能查到第一次出现的下标

let newArr=[]

let newArr = arr.filter((item, index) => {
    
    
     return arr.indexOf(item) == index
    })

2.3 for循环+indexOf

indexOf(或includex)判断新数组里是否存在,不存在则push


  function duplicate(arrT) {
    
    
      let newArr = []
      for (let i = 0; i < arrT.length; i++) {
    
    
        if (newArr.indexOf(arrT[i]) == -1) {
    
    
          newArr.push(arrT[i])
        }
      }
      return newArr
    }
   console.log( duplicate(arr))

2.4 双层for循环

  function noRepeat(arr) {
    
    
        for(var i = 0; i < arr.length-1; i++){
    
    
            for(var j = i+1; j < arr.length; j++){
    
    
                if(arr[i]===arr[j]){
    
    
                    arr.splice(j,1);
                    j--;
                }
            }
        }
        return arr;
 }
 console.log(noRepeat(arr12))

3.手写类

3.1 防抖

指触发事件后在n秒内函数只执行一次,如果在n秒内又重新触发了该事件,那么将会重新计算函数执行的时间。
场景:登录、提交按钮,发送短信等 防止多次提交

function debounce(fn, wait) {
    
    
            var timeout = null;
            return function() {
    
    
                if(timeout !== null)
                    clearTimeout(timeout);
                timeout = setTimeout(fn, wait);
            }
        }
        // 处理函数
        function handle() {
    
    
            console.log(Math.random());
        }
        // 滚动事件
        window.addEventListener('scroll', debounce(handle, 1000));

3.2 节流

思路:保证一个时间一定时间内只执行一次,若有事件正在执行,则return。
场景:

  • 鼠标连续不断地触发某事件(如点击),单位时间内只触发一次
  • 监控浏览器resize
   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);
            };
        }

        function sayHi(e) {
    
    
            console.log('节流:', e.target.innerWidth, e.target.innerHeight);
        }
        window.addEventListener('resize', throttle(sayHi, 500));

3.3 不含有重复字符串的最长子串(蚂蚁)

例:

 input: abcabcbb    output: 3
 input: bbbbb       output: 1
 input: iwwkee      output : wke 3

自己实现:

  function solution(str){
    
    
            let finalSet=new Set()
            let finalLength=0
            for(let i=0;i<str.length;i++){
    
    
                if(!finalSet.has(str[i])){
    
    
                    finalSet.add(str[i])
                    finalLength++
                }
                
            }
            return finalLength
        }
        let s='asdftya'
        console.log(solution(s))

参考答案:


        function solution(str: string): number {
    
    
            let set = new Set()
            let length = 0
            let maxLength = 0
            for (let i = 0; i < str.length; i++) {
    
    
                if (!set.has(str[i])) {
    
     //不存在
                    set.add(str[i])
                    length++
                } else {
    
     //存在
                    maxLength = Math.max(maxLength, length)
                    length = 0
                }
            }
            return maxLength
        }

3.4 给定一个二维数组,转换为对象(达摩院)

     Input : [
            ["John", 12],
            ["Jack", 13],
            ["Matt", 14],
            ["Maxx", 15]
        ]

       Output : {
    
    
            "John": 12,
            "Jack": 13,
            "Matt": 14,
            "Maxx": 15
        }

实现:

 function handleArr(arr) {
    
    
            let finalObj={
    
    }
            for (let i = 0; i < arr.length; i++) {
    
    
                let item = arr[i]
                finalObj[item[0]]=item[1]
            }
            return finalObj
        }
   console.log(handleArr(Input))

在这里插入图片描述

3.5 手写promise

3.6 手写instanceof

b instance a :判断b是否为a的实例
即:b的原型指向a的prototype
实现:

   //迭代实现
        function instanceOf(obj, constructor) {
    
    
            //取constructor的原型
            let prototype = constructor.prototype;
            //取obj的原型
            obj = obj.__proto__;
            while (true) {
    
    
                if (obj === prototype)
                    return true;
                obj = obj.__proto__;
                if (obj === null)
                    return false;
            }
        }

3.7 深拷贝

1.Object.assign(空对象名,要复制的对象名)
一层实现(深拷贝),2、多层实现(浅拷贝))
在这里插入图片描述
2.JSON.parse
函数、undefined无法拷贝
在这里插入图片描述
3.手写方法

JSON.parse(JSON.stringify())
 function deepClone(obj) {
    
    
            if (typeof obj !== 'object') {
    
    
            //简单数据类型直接返回
                return obj
            }
            let newObj = {
    
    }
            for (let i in obj) {
    
    
                newObj[i] = deepClone(obj[i])
            }
            return newObj
        }

升级版:

function deepClone(obj) {
    
    
      if (obj === null) return null; //null 的情况
      if (obj instanceof RegExp) return new RegExp(obj); //正则表达式的情况
      if (obj instanceof Date) return new Date(obj); //日期对象的情况
      if (typeof obj == 'Function') return new function(obj){
    
    }; //函数的情况
      if (typeof obj != "object") {
    
    
        //非复杂类型,直接返回 也是结束递归的条件
        return obj
      }
      //[].__proto__.constructor=Array()  []
      //{}.__proto__.constructor=Object()  {}
      //因此处理数组的情况时,可以取巧用这个办法来new新对象
      var newObj = new obj.__proto__.constructor;
      for (var key in obj) {
    
    
        newObj[key] = deepClone(obj[key])
      }
      return newObj;
    }

3.8 跳马(字节二面)

在这里插入图片描述
代码:

 // 注意象棋棋盘是7 * 7,然后象棋每次跳日
        // let count = 0
        function solution(x0, y0, xn, yn, n) {
    
    
            // 递归出口
            if (n == 0) {
    
    
                if (x0 == xn && y0 == yn) {
    
    
                    // count++
                    return 1
                }
                return 0
            }
            let arr = getNextSteps(x0, y0)
            let sum = 0
            console.log(arr);
            for (let i = 0; i < arr.length; i++) {
    
    
                sum += solution(arr[i][0], arr[i][1], xn, yn, n - 1)
            }
            return sum
        }
        let c = solution(0, 0, 5, 6, 5)
        // console.log(count);
        console.log(c);
        // 用于判断它的下一步跳的情况,在最中间时一共有8种跳跃情况
        function getNextSteps(x, y) {
    
    
            let arr = []
            // 往第一象限跳
            if (x <= 4 && y >= 1) {
    
    
                arr.push([x + 2, y - 1])
            }
            if (x <= 5 && y >= 2) {
    
    
                arr.push([x + 1, y - 2])
            }
            // 往第二象限跳
            if (x >= 2 && y >= 1) {
    
    
                arr.push([x - 2, y - 1])
            }
            if (x >= 1 && y >= 2) {
    
    
                arr.push([x - 1, y - 2])
            }
            // 往第三象限跳
            if (x >= 2 && y <= 5) {
    
    
                arr.push([x - 2, y + 1])
            }
            if (x >= 1 && y <= 4) {
    
    
                arr.push([x - 1, y + 2])
            }
            // 往第四象限跳
            if (x <= 4 && y <= 5) {
    
    
                arr.push([x + 2, y + 1])
            }
            if (x <= 5 && y <= 4) {
    
    
                rr.push([x + 1, y + 2])
            }
            return arr
        }
// let arr = getNextSteps(0, 0)
// console.log(arr);

3.9 获取url参数

给定一个url:
“http://www.baidu.com?name=张三&age=25&sex=男&wife=小红”
输出图片结果:
在这里插入图片描述

 let URL = "http://www.baidu.com?name=张三&age=25&sex=男&wife=小红"
        function getUrlParams(url) {
    
    
            // 通过 ? 分割获取后面的参数字符串
            let urlStr = url.split('?')[1]
            // 创建空对象存储参数
            let obj = {
    
    };
            // 再通过 & 将每一个参数单独分割出来
            let paramsArr = urlStr.split('&')
            for (let i = 0, len = paramsArr.length; i < len; i++) {
    
    
                // 再通过 = 将每一个参数分割为 key:value 的形式
                let arr = paramsArr[i].split('=')
                obj[arr[0]] = arr[1];
            }
            return obj
        }
        console.log(getUrlParams(URL))

        function handleUrl(u) {
    
    
            let urlStr = u.split('?')[1]
            let paramArr = urlStr.split('&')
            let final = []
            for (let i = 0; i < paramArr.length; i++) {
    
    
                let item = paramArr[i].split('=')
                final.push(item[0])
            }
            return final
        }
        console.log(handleUrl(URL))

3.10 第一个只出现一次的字符(美团)

在一个长字符串中找到第一个只出现一个的字符,并返回它的位置,如果没有则返回-1(需区分大小写),从0开始计数。

数据范围:0<=n<=10000,且字符串只有字母组成
要求:空间复杂度O(n) , 时间复杂度O(n)

示例:

输入 :"google"
输出:4

输入:"aa"
输出:-1

代码:

function handleFirst(s) {
    
    
            for (let i = 0; i < s.length; i++) {
    
    
                a = s.indexOf(s[i])
                b = s.indexOf(s[i], a + 1)
                if (b == -1) {
    
    
                    return i;
                }

            }
            return -1;
        }

3.11 判断括号是否有效(美团)

猜你喜欢

转载自blog.csdn.net/weixin_44247866/article/details/127575470