前端面试-笔试题

手写深克隆

function myDeepClone(obj) {
  if(!obj) return obj
  if(obj instanceof Array){//数组类型
    let result=[]
    let len = obj.length
    for(let i=0;i<len;i++){
      let cur=obj[i]
      if(typeof cur==='object'){
        result[i]=myDeepClone(cur)
      }else{
        result[i]=cur
      }
    }
    return result
  }
  if(obj instanceof Object){//对象类型
    let result={}
    for(let i in obj){
      let cur=obj[i]
      if(typeof cur==='object'){
        result[i]=myDeepClone(cur)
      }else{
        result[i]=cur
      }
    }
    return result
  }
}

深克隆实现方式:1、如上的手写递归(我自己写的,可能不准确);2、JSON的序列化和返序列化:JSON.parse(JSON.stringify());3、第三方库:lodash的cloneDeep:_cloneDeep(),jQuery的extend:$.extend(true,{},obj)。

在对于对象或数组中含有函数或循环引用的情况下,使用 JSON.parse(JSON.stringify(obj)) 可能会出错。因为 JSON 格式本身不支持存储函数和循环引用,所以在进行序列化和反序列化操作时会忽略掉这些内容,导致深拷贝不完整或出现异常。

面经经常提到深拷贝,浅拷贝也别忽视了,有一次就被问到了。。。

首先了解什么是浅拷贝?对于网上的众多说法,我个人觉得一下这种解释最为恰当:浅拷贝是会将对象的每个属性进行依次复制,但是当对象的属性值是引用类型时,实质复制的是其引用,当引用指向的值改变时也会跟着变化。深拷贝和浅拷贝是针对复杂数据类型(对象及数组)来说的,浅拷贝只拷贝一层,而深拷贝是层层拷贝。

浅拷贝实现方式:1、展开运算符:let obj1={a:1,b:2};let obj2={...obj1};2、Object.assign(target,data1,data2...),用法:let copyData=Object.assign({},obj1);3、拷贝数组可以使用数组的slice(),如:const arr = [1, 2, { a: 3 }]; const shallowCopy = arr.slice();

试一下就知道了~

const obj = { a: 1, b: { c: 2 } };
const shallowCopy = { ...obj };
obj.a=2;
console.log(shallowCopy);//{ a: 1, b: { c: 2 } }
console.log(obj);//{ a: 2, b: { c: 2 } }

obj.b.c=4;
console.log(shallowCopy);//{ a: 1, b: { c: 4 } }
console.log(obj);//{ a: 2, b: { c: 4 } }

结论就是:浅拷贝只拷贝第一层。

有特殊元素的数组去重

//输入[1,'ww',null,undefined,{},'ww',{},null]
//输出[1,'ww',null,undefined,{}]
function duplicateRemoval(arr){
    let result=[]
    let set=new Set()
    arr.forEach(item=>{
        if(typeof item==='object'){
            let str=JSON.stringify(item)
             if(!set.has(str)){
                set.add(str)
                result.push(item)
            }
        }else{
            if(!set.has(item)){
                set.add(item)
                result.push(item)
            }
        }
    })
    return result;
}

上面是标准做法,我个人只能想到比较孬的做法。

function dd(arr){
  const set = {};
  const result = [];
  arr.forEach(item => {
    if (typeof item === 'object') {
      const str = JSON.stringify(item);
      if (!set[str]) {
        set[str]=1;
        result.push(item);
      }
    } else {
      if (!set[item]) {
        set[item]=1;
        result.push(item);
      }
    }
  });
  return result;
};

但是!我发现这个方法有bug!像123和'123'这种,会被视为相同元素而被去重。所以还是得用上面那个方法。

闭包实现防抖功能

function antiShaking(func,delay){
    let timer=null;
    return function(){
        const _this=this
        const args=arguments
        clearTimeout(timer)
        timer=setTimeout(function(){
            func.apply(_this,args)
        },delay)
    }
}

猜你喜欢

转载自blog.csdn.net/ifmushroom/article/details/129831722