前端常见手写代码题集

1. 手写Object.create

思路:将传入的对象作为原型

function create(obj) {
  function F() { }
  F.prototype = obj
  return new F()
}

2. 手写 instanceof

思路:不断地从左边的原型链上去找

function MyInstanceof(left, right) {
  let l = Object.getPrototypeOf(left);
  let r = right.prototype;

  while (1) {
    if (!l) return false;
    if (l === r) return true;

    l = Object.getPrototypeOf(l)
  }
}

3. 手写 new 操作符

思路:

  • 创建一个空对象
  • 设置原型对象
  • this指向这个对象
function myNew(fn) {
  let obj = {};
  obj.__proto__ = fn.prototype;
  let res = fn.call(obj);
  return typeof res === 'object' ? res : obj
}

4. 手写 Promise.all

直接写

function MyPromiseAll(promises) {
  return new Promise((resolve, reject) => {
    let count = 0;
    let res = [];

    promises.forEach((promise, index) => {
      Promise.resolve(promise)
        .then((value) => {
          count++;
          res[index] = value;

          if (count === promises.length) {
            return resolve(res)
          }
        })
        .catch((err) => reject(err))
    })
  })
}

5. 手写 Promise.race

思路:返回第一个有结果的promise

function MyPromiseRace(promises) {
  return new Promise((resolve, reject) => {
    for (let i = 0; i < promises.length; i++) {
      promises[i].then(resolve, reject)
    }
  })
}

6. 手写 Promise.allsettled

function allsettled(promises) {
  return new Promise((resolve, reject) => {
    const res = [];
    let count = 0;

    for (let i = 0; i < promises.length; i++) {
      promises[i]
        .then((value) => res[i] = { status: 'fulfilled', value })
        .reject((reason) => res[i] = { status: 'rejected', reason })
        .finally(() => {
          count++;
          if (count === promises.length) {
            resolve(res)
          }
        })
    }
  })
}

7. 手写防抖、节流

// 防抖
function debounce(fn, wait) {
  let timer = null;

  return function (...args) {
    const context = this;

    if (timer) {
      clearTimeout(timer);
      timer = null;
    }

    timer = setTimeout(() => {
      fn.apply(context, args);
    }, wait)
  }
}

// 节流
function throttle(fn, wait) {
  let timer = null;

  return function (...args) {
    const context = this;

    if (timer) {
      return
    }

    timer = setTimeout(() => {
      fn.apply(context, args);
      timer = null;
    }, wait)
  }
}

附加节流和防抖的应用场景:

  • 节流:
    1. 监听滚动事件
    2. 调整窗口大小页面跟着变
    3. 输入框实时搜索
  • 防抖:
    1. 用户输入的触发事件
    2. 表单提交
    3. 延迟加载

8. 手写call、apply、bind

Function.prototype.myCall = function (context, ...args) {
  context = context || window
  args = args || []
  const key = new Symbol()
  context[key] = this
  const res = context[key](...args)
  delete context[key]
  return res
}

Function.prototype.myApply = function (context, args) {
  context = context || window
  args = args || []
  const key = new Symbol()
  context[key] = this
  const res = context[key](...args)
  delete context[key]
  return res
}

Function.prototype.myBind = function (context, ...args) {
  let self = this
  args = args || []
  return function (...newargs) {
    const key = Symbol()
    context[key] = self
    const res = context[key](...args, ...newargs)
    delete context[key]
    return res
  }
}

9. 手写AJAX请求

const url = '/server';
let xhr = new XMLHttpRequest();

xhr.open('GET', url, true);
xhr.onreadystatechange = function () {
  if (this.readyState !== 4) return;

  if (this.status === 200) {
    console.log(this.response);
  } else {
    console.log(this.statusText);
  }
}

xhr.onerror = function () {
  console.log(this.statusText);
}

xhr.responseType = 'json';
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(null);

10. 手写深、浅拷贝

10.1 浅拷贝

  1. Object.assign()
  2. 扩展运算符

10.2 深拷贝

  1. JSON.stringify()
  2. lodash库
  3. 手写深拷贝
    function deepClone(obj, map = new WeakMap()) {
      if (obj === null || typeof obj !== 'object' || map.has(obj)) {
        return obj;
      }
    
      map.set(obj, true)
      let newObj = Array.isArray(obj) ? [] : {};
      for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
          newObj[key] = deepClone(obj[key]);
        }
      }
    
      return newObj;
    }
    
    

11. 一行实现sleep函数

function sleep(delay) {
  return new Promise(resolve => setTimeout(resolve, delay))
}

你可能感兴趣的:(面试题,前端,javascript,开发语言)