前端面试-手写代码

92 阅读2分钟

防抖节流

防抖

防抖(Debounce)是指在事件被触发 delay 时间后再执行回调 function 函数,如果在这设置的 delay 时间内事件又被触发,则重新计时。这可以使用在些点击请求的事件上,避免因为用户的多次点击向后端发送多次请求。

function debounce(fn, wait) {
    var timer = null;
    return function () {
        var context = this
        if(timer) {
            clearTimeout(timer);
            timer = null;
        } else {
            timer =setTimeout(() => {
                fn.apply(context, ...arguments);
            },wait)
        }
    }
}

节流

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

function throttle(fn, wait) {
    var timer = null;
    return function() {
        var context = this
        if(!timer) {
            timer = setTimeout(()=> {
                fn.apply(context, ...arguments);
                timeout = null
            },wait)
        }
    }
}

Promise相关

手写Promise.all

Promise.MyAll = function (promises) {
  let arr = [],
    count = 0
  return new Promise((resolve, reject) => {
    promises.forEach((item, i) => {
      Promise.resolve(item).then(res => {
        arr[i] = res
        count += 1
        if (count === promises.length) resolve(arr)
      }).catch(reject)
    })
  })
}

手写Promise.race

Promise.MyRace = function (promises) {
  return new Promise((resolve, reject) => {
    // 这里不需要使用索引,只要能循环出每一项就行
    for (const item of promises) {
      Promise.resolve(item).then(resolve, reject)
    }
  })
}

手写Promise.allSettled

Promise.MyAllSettled = function (promises) {
  let arr = [],
    count = 0
  return new Promise((resolve, reject) => {
    promises.forEach((item, i) => {
      Promise.resolve(item).then(res => {
        arr[i] = { status: 'fulfilled', val: res }
        count += 1
        if (count === promises.length) resolve(arr)
      }, (err) => {
        arr[i] = { status: 'rejected', val: err }
        count += 1
        if (count === promises.length) resolve(arr)
      })
    })
  })
}

函数柯里化

函数柯里化,其实就是把一个接受多个参数的函数,转变成接受一个单一参数,且返回接受剩余参数并能返回结果的新函数的技术。

add(1)(2)(3)、add(1,2)(3)、add(1,2,3)

const curry = function (fn, ...a) {
  // 实参数量大于等于形参数量吗?
  return a.length >= fn.length ?
    // 如果大于返回执行结果
    fn(...a) :
    // 反之继续柯里化,递归,并将上一次的参数以及下次的参数继续传递下去
    (...b) => curry(fn, ...a, ...b);
};
const add = (a, b, c) => a + b + c;
// 将add加工成柯里化函数
const addCurry = curry(add);
console.log(addCurry(1, 2, 3));// 6
console.log(addCurry(1)(2)(3));// 6
console.log(addCurry(1, 2)(3));// 6
console.log(addCurry(1)(2, 3));// 6