返回

JS 手写题精选,挑战你的编程思维

前端

实现 new 过程

实现 JavaScript 中的 new 运算符,该运算符可以创建一个新对象。

要点:

  • 函数第一个参数是构造函数。
  • 实例的 __proto__ 指向构造函数的原型属性 prototype
  • 函数剩余参数要挂载到一个实例对象上。
  • 构造函数有返回值时,就返回这个返回值。

代码实现:

function newOperator(constructor, ...args) {
  // 创建一个新的对象
  const obj = Object.create(constructor.prototype);

  // 将函数剩余参数挂载到实例对象上
  for (const arg of args) {
    obj[arg] = arg;
  }

  // 如果构造函数有返回值,就返回这个返回值
  const result = constructor.apply(obj, args);
  if (typeof result === 'object' && result !== null) {
    return result;
  }

  // 否则返回实例对象
  return obj;
}

深拷贝

实现一个 deepCopy 函数,该函数可以对一个对象进行深拷贝。

要点:

  • 使用 JSON.stringify()JSON.parse() 可以实现深拷贝。
  • 对于非对象和非数组的数据类型,直接返回即可。
  • 对于对象和数组,使用递归的方式进行深拷贝。

代码实现:

function deepCopy(obj) {
  // 如果是对象或数组,则使用 JSON.stringify() 和 JSON.parse() 实现深拷贝
  if (typeof obj === 'object' && obj !== null) {
    return JSON.parse(JSON.stringify(obj));
  }

  // 否则直接返回
  return obj;
}

实现一个发布/订阅模式

实现一个发布/订阅模式,该模式可以允许订阅者订阅发布者的事件,当发布者发布事件时,订阅者会收到通知。

要点:

  • 使用一个对象来存储发布者和订阅者。
  • 当发布者发布事件时,遍历所有订阅者并调用它们的回调函数。

代码实现:

class PubSub {
  constructor() {
    this.subscribers = {};
  }

  subscribe(eventName, callback) {
    // 如果该事件不存在,则创建一个新的数组
    if (!this.subscribers[eventName]) {
      this.subscribers[eventName] = [];
    }

    // 将回调函数添加到该事件的订阅者数组中
    this.subscribers[eventName].push(callback);
  }

  publish(eventName, data) {
    // 如果该事件存在,则遍历所有订阅者并调用它们的回调函数
    if (this.subscribers[eventName]) {
      for (const callback of this.subscribers[eventName]) {
        callback(data);
      }
    }
  }
}

实现一个二叉树

实现一个二叉树数据结构,该数据结构可以存储数据并提供一些基本操作,如插入、删除、查找等。

要点:

  • 二叉树中的每个节点都有一个值和两个子节点,即左子节点和右子节点。
  • 可以使用递归的方式来实现二叉树的操作。

代码实现:

class BinaryTree {
  constructor(value) {
    this.value = value;
    this.left = null;
    this.right = null;
  }

  insert(value) {
    // 如果该节点没有左子节点,则将该值插入左子节点
    if (!this.left) {
      this.left = new BinaryTree(value);
    }

    // 否则,将该值插入右子节点
    else {
      this.right = new BinaryTree(value);
    }
  }

  delete(value) {
    // 如果该节点没有左子节点,则将该值插入左子节点
    if (!this.left) {
      this.left = null;
    }

    // 否则,将该值插入右子节点
    else if (!this.right) {
      this.right = null;
    }

    // 否则,递归地删除该值
    else {
      this.left.delete(value);
      this.right.delete(value);
    }
  }

  find(value) {
    // 如果该节点的值等于该值,则返回该节点
    if (this.value === value) {
      return this;
    }

    // 否则,递归地查找该值
    else if (this.left) {
      const foundNode = this.left.find(value);
      if (foundNode) {
        return foundNode;
      }
    }

    else if (this.right) {
      const foundNode = this.right.find(value);
      if (foundNode) {
        return foundNode;
      }
    }

    // 如果没有找到该值,则返回 null
    return null;
  }
}

希望这些手写题能帮助你提升 JavaScript 编程技能。