初级前端面试题(二)之 JavaScript

发布时间:2024年01月19日

1.? 手写节流、防抖

节流【相当与技能冷却中,或者用户频繁点击按钮】

//假设你要实现技能冷却中,要怎么实现?
//假设你要调用闪现,但是在闪现过程中的120秒内你再次调用闪现,不会做任何事情,因为正在冷却中


const d=(distance)=>{ //闪现的函数
   console.log('闪现')
},

//实现任意函数的节流
const abcFn=(f,time)=>{
  let timer=null;
  let lengQue=false; 
   return (...args)=>{
      if(lengQue){
    return
  }else{
     f(...args);//调用闪现的函数
     lengQue=true;
     timer=setTimeout(() => {
        // 方法区
        lengQue= false;
        timer=null
      }, time);
  }
     
   }
}

//调用函数
const da=abcFn(d,120*1000)

防抖【相当于回城,或者拖动页面时】

//打断后重新计时

const f=()=>{
  console.log('回城成功');
}

const debounce=(f,time)=>{
 let timer=null;
 return (...args)=>{
   if(timer!=null){
     clearTimerout(timer); //清空timer
   }else{
      timer=setTimerout(()=>{
         f(...args);
         timer=null
      },time)
   }
 }
 
}

//调用
const tp=debounce(f,3000)
tp(); //3秒之后才会‘回城成功’



2.?手写发布订阅

发布订阅是非常著名的设计模式。

? ? 例如:你刷博客之类的,遇到感兴趣的会去关住他,去看他的内容,但他下次发布新内容时,网站会通过一些方法通知到我们,我们也会在第一时间了解到这些新内容,但至于会不会第一时间去看就起决于我们自己了。

const eventHub={
   //queue:[] //一般使用q来代表数组
   queueMap:{}, //在js里用空对象表示哈希表
    on:(name,fn)=>{
      eventHub.queueMap[name]=eventHub.map[name]||[];//取他的第name个,如果是空的就初始化(取后面  的 值)
      eventHub.queueMap[name].push(fn)
   //return undefined
   },
    emit:(name,data)=>{ //把队列里的东西调用一下
        const q=eventHub.queueMap[name]
        if(!q){return}  //判断是否为空,若为空,就短路了什么也不用做
        q.map(f=>f(data) //遍历。foreach、map但map有返回值
        return undefined},
    off:(name,fn)=>{
        //这是只是读,可以给eventHub.queueMap[name]做别名
      if(!eventHub.queueMap[name]){return}
      const index=eventHub.map[name].indexOf(fn)
        if(index<0){return } //短路法
        eventHub.map[name].splice(index,1) //splice 是设置要删除的索引
      }
}
//监听两次click,调用两次函数
eventHub.on('click',console.log)
eventHub.on('click',console.error)

//3秒钟后触发click
setTimeout(()=>{ 
    eventHub.emit('click','frank')
},3000)

3.?深浅拷贝

  • 浅拷贝:只拷贝一层 object.assign(target,sources);
  • 深拷贝:不会只传地址,而会开辟一个新的空间,赋值给另一个空间

参考:【js进阶】-深浅拷贝_js深拷贝-CSDN博客

4.?promise

(1)? 地址ES6 入门教程

(2)? 概念:promise 是异步编程的一种解决方案。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

(3)? 三种状态:pending (进行中)? ? ? ? ? resoloved (已完成)? ? ? ? ? ? ? ? ? ?rejected (已失败)

(4)? 基本用法:

const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 异步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});


promise 
  .then(function (a){})
  .catch(function(error){})
  .finally(()=>{})

ps: finally优点: 1)成功和失败的情况只需要写一次; 2)会返回原来的值

(5)?常用方法:

5.1? Promise.all([p1,p2])

1)都返回resolve(); 才能够拿到成功的返回值;

2)有一个返回reject(), 则进入catch(error), 拿到失败的返回值。

5.2? promise.race([p1,p2,p3])

? ? ?只要p1p2p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

5.3? promise.allSettled()

? ? ?只有等到参数数组的所有 Promise 对象都发生状态变更(不管是fulfilled还是rejected),返回的 Promise 对象才会发生状态变更。

5.4? promsie.any()

? ?Promise.any()Promise.race()方法很像,只有一点不同,就是Promise.any()不会因为某个 Promise 变成rejected状态而结束,必须等到所有参数 Promise 变成rejected状态才会结束.

5.?扩展运算符

对象扩展运算符 (...)

let ab={a:"erer",b:123};
let ac={... ab}; // 等价于 let ac=Object.assign({},ab)
console.log(ac); //{a: 'erer', b: 123}

6.手写ajax

//首先申明一个对象
var xhr =new XMLHttpRequest()
//发请求发到哪个地方呢(路径)
xhr.open('GET','/XXX')
//监听onreadystatechange事件
xhr.onreadystatechange=function()
{
    if (xhr.readyState == 4) //4是下载操作已完成
    {     //看它的状态码,如果在这个区间内说明成功了
        if (xhr.status >= 200 && xhr.status < 300||xhr.status===304) 
        {
            success(xhr)
        }
        else
        {
            fail(xhr)
        }
    }
};
//一般是全都设置好之后再发送,所以习惯吧send写在最下面    
//设置请求体,get一般是空的,post是传一个json数据
xhr.send('{"name":"frank"}')

文章来源:https://blog.csdn.net/CMDN123456/article/details/134015664
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。