2024 javascript前端面试手撕代码 deepequal,deepcopy,浅拷贝深拷贝,手写防抖节流,手写promise.all promise.race,拉平数组,实现new操作符原理
Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。⚠️`catch(err=>reject(err))` 和`catch(err=>console.log(err))`节流,单位时间内只执行一次,比如scroll和resize事件。递归判断俩对象是否相等。
·
目录
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"];
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐



所有评论(0)