返回

面试常考手撕源码题

前端

手撕源码题是面试中经常遇到的难题,它考验的是应聘者的编程能力和对计算机科学基础知识的掌握程度。本文将介绍几种常见的手撕源码题,并提供详细的解答和代码实现。这些题目涵盖了JavaScript、算法、数据结构、设计模式等多个方面,对于准备面试的程序员来说非常有帮助。

1. 手写防抖节流

防抖和节流都是用来控制函数执行频率的技巧,在前端开发中非常常用。

  • 防抖:当函数被连续多次调用时,只执行最后一次调用。
  • 节流:当函数被连续多次调用时,只执行第一次调用,然后在一段时间内不执行任何调用。
// 防抖
function debounce(func, wait) {
  let timeout;
  return function(...args) {
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      func.apply(this, args);
    }, wait);
  };
}

// 节流
function throttle(func, wait) {
  let lastCallTime = 0;
  return function(...args) {
    const now = Date.now();
    if (now - lastCallTime >= wait) {
      func.apply(this, args);
      lastCallTime = now;
    }
  };
}

2. 手写EventEmitter

EventEmitter是Node.js中常用的事件发布订阅模式的实现。它允许对象之间通过事件来进行通信。

class EventEmitter {
  constructor() {
    this.events = {};
  }

  on(eventName, listener) {
    if (!this.events[eventName]) {
      this.events[eventName] = [];
    }
    this.events[eventName].push(listener);
  }

  emit(eventName, ...args) {
    if (this.events[eventName]) {
      this.events[eventName].forEach(listener => listener.apply(this, args));
    }
  }

  removeListener(eventName, listener) {
    if (this.events[eventName]) {
      this.events[eventName] = this.events[eventName].filter(l => l !== listener);
    }
  }
}

3. 手写new操作符

new操作符是JavaScript中用来创建对象的一种方式。它首先会创建一个新的对象,然后将对象的原型指向构造函数的prototype属性。最后,它会调用构造函数,并把构造函数中的this指向新创建的对象。

function newOperator(ctor, ...args) {
  // 创建一个新对象
  const obj = {};

  // 将对象的原型指向构造函数的prototype属性
  obj.__proto__ = ctor.prototype;

  // 调用构造函数,并把构造函数中的this指向新创建的对象
  const result = ctor.apply(obj, args);

  // 返回新创建的对象
  return result || obj;
}

4. 手写instanceof

instanceof操作符用来判断一个对象是否是某个构造函数的实例。

function instanceOf(obj, ctor) {
  while (obj) {
    if (obj === ctor.prototype) {
      return true;
    }
    obj = obj.__proto__;
  }
  return false;
}

以上只是几种常见的手撕源码题,还有很多其他类型的题目。对于准备面试的程序员来说,掌握这些题目的解答方法非常重要。通过练习这些题目,可以提高自己的编程能力和对计算机科学基础知识的掌握程度。