【面试】整理了一些常考的前端面试题,以及实际被问到的问题

🪐背八股文最好结合实际项目,理解式的记下来

JavaScript

一、手写函数

1. 防抖
function debounce(func, delay, immediate) {
   
   
  let timer
  return function() {
   
    // 闭包
    let _this = this
    let arg = arguments
    if (timer) clearTimeout(timer) // 重复触发,重新开始计时
    if (immediate) {
   
    // 立即执行
      let callNow = !timer // 定时器是空的,说明可以执行
      timer = setTimeout(() => {
   
    // 开始计时
        timer = null // 计时结束后将timer置空,下一次立即执行
      }, delay);
      if (callNow) {
   
    func.apply(_this, arg) }
    } else {
   
    // 非立即执行
      timer = setTimeout(() => {
   
   
        func.apply(_this, arg) // 计时结束后执行
      }, delay);
    }
  }
}

// 第三个参数为true表示立即执行,为空或者false表示非立即执行
box.addEventListener('mouseover', debounce(function() {
   
   
  box.innerHTML = i++
}, 2000, true))
2.节流
// 定时器版
function throttle1(func, wait) {
   
   
  let pre = 0
  return function() {
   
   
    let _this = this
    let arg = arguments
    let now = new Date()
    if (now - pre > wait) {
   
   
      func.apply(_this, arg)
      pre = now
    }
  }
}


// 时间戳版
function throttle2(func, wait) {
   
   
  let timer
  return function() {
   
   
    let _this = this
    let arg = arguments
    if (!timer) {
   
   
      timer = setTimeout(() => {
   
   
        timer = null
        func.apply(_this, arg)
      }, wait);
    }
  }
}

box4.addEventListener('mouseover', throttle2(function() {
   
   
  box4.innerHTML = i4++
}, 1000))
3. 深拷贝
// 先自己写一个判断数据类型的方法
function typeOf(param) {
   
   
  const res = Object.prototype.toString.call(param).replace(/(\[|\]|object)/g, '').trim().toLowerCase()
  return res
}
// 手写深克隆
function deepClone(obj) {
   
   
  // 首先判断参数是基本数据类型还是引用数据类型
  if (typeOf(obj) === 'object' || typeOf(obj) === 'array') {
   
    // 引用数据类型
    // 进一步判断是对象还是数组
    let newObj = typeOf(obj) === 'object' ? {
   
   } : []
    for (let k in obj) {
   
   
      if (typeOf(obj[k]) === 'object' || typeOf(obj[k]) === 'array') {
   
   
        newObj[k] = deepClone(obj[k]) // 递归克隆
      } else {
   
   
        newObj[k] = obj[k]
      }
    }
    return newObj
  } else {
   
    // 基本数据类型
    // 直接返回原数据
    return obj
  }
}
const decoObj1 = deepClone(obj)
4. 数组去重/数组乱序
数组去重
// 第一种: 6ES的Set方法
res = [...new Set(arr)]
res = Array.from(new Set(arr)) // [12, 20, 13, 5]

// 第二种:循环比较(拿后一项与当前项比较)
for (let i = 0; i < arr.length - 1; i++) {
   
   
  let cur = arr[i] // 当前项
  let args = arr.slice(i +1) // 剩余的项
  const index = args.indexOf(cur)
  if (index !== -1) {
   
    // 说明有重复的
    // 遇到重复的,拿最后一项来替换,这样就不需要每次都改变index,结果 [5, 20, 12, 13]
    arr[i] = arr[arr.length - 1]
    i-- // 从当前项(原本的最后一项)开始继续比较
    arr.length-- // 去掉最后一项
  }
}

// 从最后一项开始循环, [12, 20, 13, 5]保证了顺序
for (let i = arr.length-1; i >= 0; i--) {
   
   
  let cur = arr[i]
  let args = arr.slice(0, i)
  if (args.indexOf(cur) !== -1) {
   
    // 重复项
    arr.splice(i, 1)
  }
}

// 第三种:对象法, 顺序不变[12, 20, 13, 5]
let obj = {
   
   }
for (let i = 0; i < arr.length; i++) {
   
   
  let cur = arr[i
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值