面试题目总结

手写深度比较,模拟lodash中的isEqual

// 判断是否是object
    function isObject(obj){
        return typeof obj === 'object' && obj !== null
    }
    // 全相等
    function isEqual(obj1,obj2){
        if(!isObject(obj1)||!isObject(obj2)){
            return obj1 === obj2
        }
        if(obj1 === obj2){
            return true
        }
        // 两个都是引用类型,深度比较全相等
        // 1.比较keys的个数是否相同
        const obj1Keys = Object.keys(obj1)
        const obj2Keys = Object.keys(obj2)
        if(obj1Keys.length!==obj2Keys.length){
            return false
        }
        // 2.以obj1为基准。和obj2以此递归比较
        for (const key in obj1) {
            const res = isEqual(obj1[key],obj2[key])
            if(!res){
                return false
            }
        }
        // 3.全相等
        return true

    }

    // 测试
    const obj1 = {
        a:100,
        b:{
            x:100,
            y:200
        }
    }
    const obj2 = {
        a:100,
        b:{
            x:100,
            y:200
        }
    }
    console.log(isEqual(obj1,obj2));

split和join

  • split:字符串转数组
  • join:数组转字符串

数组的pop push unshift shift分别做什么

  • pop
    • 删除源数组最后一位
    • 返回删除的最后一位
  • push
    • 添加至源数组最后一位
    • 返回添加后的数组length
  • unshift
    • 添加至源数组第一位
    • 返回添加后的数组length
  • shift
    • 删除源数组第一位
    • 返回删掉的第一位

纯函数

  • 不改变源数组
  • 返回一个新数组
  • concat
    • 拼接两个数组,返回拼接后的新数组
  • map
    • 遍历数组,返回一个新的数组
  • filter
    • 过滤数组,返回一个新数组
  • slice
    • arrayObject.slice(start,end),返回选定的新数组,源数组不变

非纯函数

  • push pop shift unshift
  • forEach
  • some every
  • reduce

数组slice和splice的区别

  • slice
    • 纯函数
    • arr.slice() 可以用作深拷贝
    • arr2 = arr.slice(1,4) 截取1-4位
    • arr2 = arr.slice(2) 截取2到最后
    • arr2 = arr.slice(-2) 倒数2位截到最后
  • splice
    • 非纯函数
    let arr = [10,20,30,40]
    let arr2 = arr.splice(2,1,'a','b','c')
    //    arr [10, 20, "a", "b", "c", 40]
    //    arr2 [30]
    // 第2位开始截取1位,把后面的替换进去
    // 返回截取的数组
    
//一道面试题
  [10,20,30].map(parseInt)
  //[10,NaN,NaN]
  // 拆解
  [10,20,30].map((num,index)=>{
      //parseInt的第二位的进制
      return parseInt(num,index)
  })

函数call和apply的区别

  • 传参方式不同 call(this,p1,p2) apply(this.[p1,p2])

闭包是什么?有什么特性?有什么影响?

  • 影响:变量会常驻内存,得不到释放

阻止事件冒泡和默认行为

  • event.stopPropagation()
  • event.preventDefault()

函数声明和函数表达式的区别

  • 函数声明 function fn(){}
  • 函数表达式 const fn = function(){}
  • 函数声明会在代码执行前预加载,函数表达式不会

new Object()和Object.create()区别

  • {}等同于new Object()
  • Object.create(null)没有原型
  • Object.create({...})可指定原型 {...}会放在一个空对象的原型中

正则表达式

  • 邮政编码 /\d{6}/
  • 小写英文字母 /^[a-z]+$/
  • 日期格式 /^\d{4}-\d{1,2}-\d{1,2}$/
  • 用户名 /^[a-zA-Z]\w{5,17}$/

多维数组转一维

function flat(arr){
    //验证是否还有深层数组
    const isDeep = arr.some(item=>item instanceof Array)
    if(!isDeep){
        return arr
    }
    const res = Array.prototype.concat.apply([],arr)
    return flat(res)//递归
}
const res = flat([1,2,[3,4,[5,6]],7])
console.log(res);

数组去重

function unique(arr){
    const res = []
    arr.forEach(item=>{
        if(res.indexOf(item)<0){
            res.push(item)
        }
    })
    return res
}
// set去重
function unique(arr){
    const set = new Set(arr)
    return [...set]
}

你可能感兴趣的:(面试题目总结)