2024 javascript前端面试手撕代码 deepequal,deepcopy,浅拷贝深拷贝,手写防抖节流,手写promise.all promise.race,拉平数组,实现new操作符原理

目录

1. deepequal函数

2. deepcopy深拷贝函数

3.浅拷贝-Object.assign

4.手写防抖

5.手写节流

6. Promise.all

7. Promise.race

8. 异步加载图片

9 reduce实现拉平数组

10 实现new操作符原理


1. deepequal函数

 function deepequal(a,b){
            if(a===b)return true;

            if((a!=null && typeof(a)==='object')&&(b!=null && typeof(b)==='object'))
            {
                //如果a和b都存在且为对象
                if(Object.keys(a).length!= Object.keys(a).length)
                return false;
                for(let key in a){
                    if(b.hasOwnProperty(key))
                    {
                        if(!deepequal(a[key],b[key]))return false;
                    }
                    else 
                    return false;
                }
                return true
            }
            else return false;
            
        }

递归判断俩对象是否相等

2. deepcopy深拷贝函数

function deepcopy(a){
            
            let obj = Array.isArray(a)?[]:{}
            for(let key in a){
                if(a.hasOwnProperty(key)){
                    if (typeof a[key] === 'object')
                        obj[key] = deepcopy(a[key])
// 递归调用 deepcopy,并将结果添加到新创建的对象或数组中
                    else
                        obj[key] = a[key]
// 如果是基本类型,则直接赋值给新创建的对象或数组
                }
            
            }
            return obj

        }
        



//下面是测试数据
        let obj1 = {
                a: 1,
                b:
                {
                    c: 2
                }
            };
            let obj2 = deepcopy(obj1)
            obj1.b = 3
            console.log(obj1, obj2)

3.浅拷贝-Object.assign

let a={
            name:['nice'],
            age:18,
            l:function(){
                console.log(this.name)
            },
            name:{
                name1:'lym',
                name2:'aa'
            }
        }
        let y = Object.assign({},a)
        a['name'].name2=18
        console.log(a,y)
//然后发现第二个变量一起变化了

浅拷贝-对象自身的可枚举属性和从原型链继承下来的

function scopy(a){

let obj={}
for(let key in a){
  if(a.hasOwnProperty(key))
  obj[key]=a[key]
 }
return obj
}

4.手写防抖

防抖,只执行最后一次,比如input框多次点击

const debounce=function(func,wait){
            let timer
            return (...args)=>{
                if(timer)timer=clearTimeout(timer)
                timer=setTimeout(()=>{
            func.apply(this,args)
            timer=null
            },wait)
            }
        }

5.手写节流

节流,单位时间内只执行一次,比如scroll和resize事件

const throttle=function(func,wait){
            let timer
            return (...args)=>{
                if(!timer){
                    timer=setTimeout(()=>{
                        func.apply(this,args)
                        timer=null
                    },wait)
                }

            }

        }

6. Promise.all

如果全部成功执行,则以数组的方式返回所有 Promise 任务的执行结果。 如果有一个Promise 任务 rejected,则只返回 rejected 任务的结果

function promiseall(promises){
            let r=[]
            let cnt=0
            
            return new Promise((resolve,reject)=>{
                for(let i=0;i<promises.length;i++)
                {
                    Promise.resolve(promises[i]).then((data)=>{
                        r[i]=data
                        cnt++
                        if(cnt===promises.length)
                        resolve(r)
                    }).catch(err=>reject(err))
                }
            })
        }

7. Promise.race

function promiserace(promises){
	return new Promise((resolve,reject)=>{

for(let i=0;i<promises.length;i++)
{
	Promise.resolve(promises[i]).then((data)=>resolve(data)).catch(error=>console.log(error))
}

	})
}

Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态

⚠️`catch(err=>reject(err))` 和`catch(err=>console.log(err))`

//测试数据:
        var  x = setTimeout(() => {
       Promise.resolve(2).then((daa)=>console.log(daa))
        // console.log(10)
        }, 1000);
        var  y= Promise.reject('wrong')
        console.log(racee([x,y]))
        // Promise.race([x,y])

8. 异步加载图片

//异步处理图片
<div id="id"></div>
        function loading(url){
            return new Promise((resolve,reject)=>{
                let x = new Image()
//document.createElement('img')
                x.onload=function(){
                    resolve(x)
                    //别写Promise.resolve(x)这是在返回一个新promise但是这里是让处理当前这个promise
                }
                x.onerror=function(){
                    reject(new Error('wrong'))
                }
                x.src=url
                资源开始加载之前正确注册事件处理程序
            })
        }

     window.onload = function () {
        loading('sg.png').then((data) => {
            document.getElementById('im').appendChild(data)
        }).catch((err) => console.log(err))
    }

9 reduce实现拉平数组

function flat(arr){
   let x = arr.reduce((pre,cur)=>{
return Array.isArray(cur)? pre.concat(flat(cur)):pre.concat(cur)
   },[])
   return x
        }

10 实现new操作符原理

function objectfactory(){
    //object.create,constructor是第一个参数,
    //创建新对象,设置原型!!,对象原型为函数的prototype对象
    //this指向对象,执行构造函数代码,如果返回的是值则忽略,如果返回引用类型则返回他
    let result=null
    let obj=null
    let constructor = Array.prototype.shift.call(arguments)
    if(typeof constructor!='function'){
        console.error('type error')
        return
    }
    obj=Object.create(constructor.prototype)
    result = constructor.apply(obj,arguments)
    let flag = result && (typeof obj==='function' ||typeof obj==='object')
    return flag? result:obj

}


//测试案例
const arr1 = [1, 2, 3, 4, [1, 2, 3, [1, 2, 3, [1, 2, 3]]], 5, "string"];

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值