面试准备之手写JS题目(持续更新)

51 阅读2分钟

前言

因为近期准备换工作,在准备面试内容。思来想去,还是应该有一个博客为未来的面试做准备,直接丢个链接给人看,也可以供自己以后复习。故用此记录一下准备面试的题目,以及解决办法。因为是准备面试的同时,所以写题目的同时也会去把相关知识点看一遍,所以会写一些相关的知识点的内容。 题目出处

1.数据类型判断

const getType = (obj) => { 
    const type = Object.prototype.toString.call(obj).split(' ')[1]
    return type.substring(0, type.length-1).toLowerCase()
}

Object.prototype返回 [Object xxx]
Function,String也有,但是toSring被重写过。

call,apply,bind可以改变this指向
区别,call,apply (obj, arg) call的arg为列表, apply的为[]
如:fn.call(obj, "1", "2") fn.apply(obj, [1,2])
call apply直接执行,bind永久绑定且不会马上执行
如: const bindFn = fn.bind(obj)
bindFn()

2.数组去重

    const unique = (arr) => {
        return arr.filter((item,index)=> arr.indexOf(item) === index)
    }
    
    const unique = (arr) => [...new Set(arr)]

3.数组扁平化

   const arr = [1,[2,3],[1,2,[33]]]
   //直接用Array的flat方法,参数为提取嵌套的深度
   arr.flat(3)
   
   const flat = (arr) => {
       let result = []
       arr.map(i=>{
           if(Array.isArray(i)){
               result = result.concat(flat(i)
           }else{
               resutl.push(i
           }
       })
       return result
   }
   
   
   // 扩展运算符把数组铺开分为多个数组,然后用concat合并起来
   const flat = (arr) => {
       while(arr.some(i=>Array.isArray(i))){
           arr = [].concat(...arr)
       }
       return arr
   }

4.深浅拷贝

浅拷贝有很多种,最简单的如...扩展运算符

深拷贝
JSON.parse(),JSON.stringify(),但是无法处理undefined, symbol,函数等

    // 简易版深拷贝, 主要问题是无法解决循环引用,而且没有对date 函数等类型的处理
    const deepClone = (obj) => {
      if (typeof obj !== "object") return;
      let newObj = Array.isArray(obj) ? [] : {};
      for (let k in obj) {
        newObj[k] = typeof obj[k] === "object" ? deepClone(obj[k]) : obj[k];
      }
      return newObj;
    };
    
    // 循环引用的例子
    const A = {a: 1}
    const B = {b: 1, c: A}
    A.c = B
    
    // 复杂版本
    const isObject = (obj) => (typeof obj === 'object' || typeof obj === 'function') && typeof obj !== null
    const deepClone = (obj, map = new WeakMap()) => {
        // 说明有引用, 重复
        if(map.get(obj)){
            return obj
         }
        const constructor = obj.constructor
        // 处理Date,RegExp
        if(constructor.name === 'Date' || constructor.name === 'RegExp'){
        return new constructor(obj)
        }
        if(isObject(obj)){
            map.set(obj,true)  // 循环引用标记
            const newObj = Array.isArray(obj)
            for(k in obj){
              newObj[k] = deepClone(obj, map)
            }
            return newObj
        }else{
        return obj
        }
    }