前端一面手写面试题总结

使用Promise封装AJAX请求

// promise 封装实现:
function getJSON(url) {
   
  // 创建一个 promise 对象
  let promise = new Promise(function(resolve, reject) {
   
    let xhr = new XMLHttpRequest();
    // 新建一个 http 请求
    xhr.open("GET", url, true);
    // 设置状态的监听函数
    xhr.onreadystatechange = function() {
   
      if (this.readyState !== 4) return;
      // 当请求成功或失败时,改变 promise 的状态
      if (this.status === 200) {
   
        resolve(this.response);
      } else {
   
        reject(new Error(this.statusText));
      }
    };
    // 设置错误监听函数
    xhr.onerror = function() {
   
      reject(new Error(this.statusText));
    };
    // 设置响应的数据类型
    xhr.responseType = "json";
    // 设置请求头信息
    xhr.setRequestHeader("Accept", "application/json");
    // 发送 http 请求
    xhr.send(null);
  });
  return promise;
}

实现一个add方法完成两个大数相加

// 题目
let a = "9007199254740991";
let b = "1234567899999999999";

function add(a ,b){
   
   //...
}

实现代码如下:

function add(a ,b){
   
   //取两个数字的最大长度
   let maxLength = Math.max(a.length, b.length);
   //用0去补齐长度
   a = a.padStart(maxLength , 0);//"0009007199254740991"
   b = b.padStart(maxLength , 0);//"1234567899999999999"
   //定义加法过程中需要用到的变量
   let t = 0;
   let f = 0;   //"进位"
   let sum = "";
   for(let i=maxLength-1 ; i>=0 ; i--){
   
      t = parseInt(a[i]) + parseInt(b[i]) + f;
      f = Math.floor(t/10);
      sum = t%10 + sum;
   }
   if(f!==0){
   
      sum = '' + f + sum;
   }
   return sum;
}

实现双向数据绑定

let obj = {
   }
let input = document.getElementById('input')
let span = document.getElementById('span')
// 数据劫持
Object.defineProperty(obj, 'text', {
   
  configurable: true,
  enumerable: true,
  get() {
   
    console.log('获取数据了')
  },
  set(newVal) {
   
    console.log('数据更新了')
    input.value = newVal
    span.innerHTML = newVal
  }
})
// 输入监听
input.addEventListener('keyup', function(e) {
   
  obj.text = e.target.value
})

实现发布-订阅模式

class EventCenter{
   
  // 1. 定义事件容器,用来装事件数组
    let handlers = {
   }

  // 2. 添加事件方法,参数:事件名 事件方法
  addEventListener(type, handler) {
   
    // 创建新数组容器
    if (!this.handlers[type]) {
   
      this.handlers[type] = []
    }
    // 存入事件
    this.handlers[type].push(handler)
  }

  // 3. 触发事件,参数:事件名 事件参数
  dispatchEvent(type, params) {
   
    // 若没有注册该事件则抛出错误
    if (!this.handlers[type]) {
   
      return new Error('该事件未注册')
    }
    // 触发事件
    this.handlers[type].forEach(handler => {
   
      handler(...params)
    })
  }

  // 4. 事件移除,参数:事件名 要删除事件,若无第二个参数则删除该事件的订阅和发布
  removeEventListener(type, handler) {
   
    if (!this.handlers[type]) {
   
      return new Error('事件无效')
    }
    if (!handler) {
   
      // 移除事件
      delete this.handlers[type]
    } else {
   
      const index = this.handlers[type].findIndex(el => el === handler)
      if (index === -1) {
   
        return new Error('无该绑定事件')
      }
      // 移除事件
      this.handlers[type].splice(index, 1)
      if (this.handlers[type].length === 0) {
   
        delete this.handlers[type]
      }
    }
  }
}

手写节流函数

函数节流是指规定一个单位时间,在这个单位时间内,只能有一次触发事件的回调函数执行,如果在同一个单位时间内某事件被触发多次,只有一次能生效。节流可以使用在 scroll 函数的事件监听上,通过事件节流来降低事件调用的频率。

// 函数节流的实现;
function throttle(fn, delay) {
   
  let curTime = Date.now();

  return function() {
   
    let context = this,
        args = arguments,
        nowTime = Date.now();

    // 如果两次时间间隔超过了指定时间,则执行函数。
    if (nowTime - curTime >= delay) {
   
      curTime = Date.now();
      return fn.apply(context, args);
    }
  };
}

Promise并行限制

就是实现有并行限制的Promise调度器问题

class Scheduler {
   
  constructor() {
   
    this.queue = [];
    this.maxCount = 2;
    this.runCounts = 0;
  }
  add(promiseCreator) {
   
    this.queue.push(promiseCreator);
  }
  taskStart() {
   
    for (let i = 0; i < this.maxCount; i++) {
   
      this.request(
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
1. 实现一个数组去重的函数 思路:使用对象来存储数组的元素,遍历数组,若元素在对象不存在,则存储到对象,并将其推入新数组。 2. 实现一个函数,判断一个字符串是否是回文字符串 思路:将字符串翻转,与原字符串比较是否相等。 3. 实现一个函数,可以将多维数组转化为一维数组 思路:使用递归来遍历多维数组,将每个元素推入新数组,直到遍历完所有元素。 4. 实现一个函数,统计一个字符串出现次数最多的字符 思路:使用对象来存储每个字符出现的次数,遍历字符串,将每个字符存储到对象,找到出现次数最多的字符。 5. 实现一个函数实现数组的冒泡排序 思路:使用双重循环遍历数组,比较相邻两个元素的大小,如果前者大于后者,则交换两个元素的位置,直到遍历完数组。 6. 实现一个函数实现数组的快速排序 思路:选择数组的一个元素作为基准点,将数组分为两个部分,一部分大于基准点,一部分小于基准点,递归处理两个部分。 7. 实现一个函数实现数组的深拷贝 思路:使用递归遍历数组的每个元素,判断元素类型,如果是对象或数组,则进行深拷贝,如果是基本类型,则直接复制。 8. 实现一个函数实现函数的柯里化 思路:使用闭包保存参数,当参数个数达到预设值时,执行函数。 9. 实现一个函数实现函数的节流 思路:使用定时器来控制函数执行的频率,每次函数执行时,清除定时器并重新设置一个定时器。 10. 实现一个函数实现函数的防抖 思路:使用定时器来延迟函数执行,每次函数执行时,清除定时器并重新设置一个定时器。如果在定时器延迟时间内再次触发函数,则重新计时。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值