Skip to content
手写代码
手写代码的一些题目
2025-06-26 09:33
AI总结: 加载中...

防抖

查看答案
js
function debounce(fn, delay) {
  let timer = null;
  return function () {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() => {
      fn.apply(this, arguments);
    }, delay);
  };
}

节流

查看答案
js
function throttle(fn, delay) {
  let starTime = 0;
  return function () {
    let nowTime = Date.now();
    if (nowTime - starTime >= delay) {
      starTime = Date.now();
      fn.apply(this, arguments);
    }
  };
}

实现 promise

查看答案
js
class MyPromise {
  constructor(executor) {
    this.status = "pending";
    this.value = null;
    this.reason = null;
    this.fulfilledCallbacks = [];
    this.rejectedCallbacks = [];

    const resolve = (value) => {
      if (this.status !== "pending") return;
      this.status = "fulfilled";
      this.value = value;
      this.fulfilledCallbacks.forEach((fn) => fn(value));
    };

    const reject = (reason) => {
      if (this.status !== "pending") return;
      this.status = "rejected";
      this.reason = reason;
      this.rejectedCallbacks.forEach((fn) => fn(reason));
    };

    try {
      executor(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }

  then(onFulfilled, onRejected) {
    return new MyPromise((resolve, reject) => {
      if (this.status === "fulfilled") {
        setTimeout(() => {
          try {
            const result = onFulfilled(this.value);
            resolve(result);
          } catch (error) {
            reject(error);
          }
        });
      } else if (this.status === "rejected") {
        setTimeout(() => {
          try {
            const result = onRejected(this.reason);
            reject(result);
          } catch (error) {
            reject(error);
          }
        });
      } else {
        this.fulfilledCallbacks.push((val) => {
          try {
            const result = onFulfilled(val);
            resolve(result);
          } catch (error) {
            reject(error);
          }
        });
        this.rejectedCallbacks.push((val) => {
          try {
            const result = onRejected(val);
            reject(result);
          } catch (error) {
            reject(error);
          }
        });
      }
    });
  }
}

手写深拷贝

查看答案
js
function deepClone(obj, hash = new WeakMap()) {
  if (obj === undefined || obj === null || typeof obj !== "object") return obj;

  if (obj instanceof Date) {
    return new Date(obj);
  }
  if (obj instanceof RegExp) {
    return new RegExp(obj);
  }
  if (hash.get(obj)) {
    return hash.get(obj);
  }

  let newObj = Array.isArray(obj) ? [] : {};
  hash.set(obj, newObj);

  Object.keys(obj).forEach((key) => {
    newObj[key] = deepClone(obj[key], hash);
  });

  return newObj;
}

手写 new 操作符

查看答案
js
function myNew(fn, ...args) {
  let obj = {};
  obj.__proto__ = fn.prototype;
  const result = fn.apply(obj, args);
  return result instanceof Object ? result : obj;
}

函数柯里化

查看答案
js
function curry(fn) {
  if (typeof fn !== "function") return;

  return function curried(...args) {
    if (args.length >= fn.length) {
      return fn.apply(this, args);
    } else {
      return function (...args2) {
        return curried.apply(this, args.concat(args2));
      };
    }
  };
}

将对象数组转化为树结构

js
const items = [
  { id: 1, name: "Item 1", parentId: null },
  { id: 2, name: "Item 1.1", parentId: 1 },
  { id: 3, name: "Item 1.2", parentId: 1 },
  { id: 4, name: "Item 2", parentId: null },
  { id: 5, name: "Item 2.1", parentId: 4 },
];
查看答案
js
function arrToTree(arr) {
  const result = [];
  const map = new Map();

  arr.forEach((item) => {
    map.set(item.id, { ...item, children: [] });
  });

  arr.forEach((item) => {
    if (item.parentId === null) {
      result.push(map.get(item.id));
    } else {
      map.get(item.parentId).children.push(map.get(item.id));
    }
  });

  return result;
}

发布-订阅模式

查看答案
js
class EventEmitter {
  constructor() {
    this.events = {};
  }

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

  emit(eventName, ...args) {
    if (!this.events[eventName]) return;
    this.events[eventName].forEach((fn) => fn(...args));
  }

  off(eventName, callback) {
    if (!this.events[eventName]) return;
    this.events[eventName] = this.events[eventName].filter(
      (fn) => fn !== callback
    );
  }
}

手写 vue

查看答案
js
class Dep {
  constructor() {
    this.subs = [];
  }

  depend() {
    if (Dep.target && !this.subs.includes(Dep.target)) {
      this.subs.push(Dep.target);
    }
  }

  notify() {
    this.subs.forEach((sub) => sub.update());
  }
}
Dep.target = null;

class Watcher {
  constructor(fn) {
    this.fn = fn;
    this.get();
  }

  get() {
    Dep.target = this;
    this.fn();
    Dep.target = null;
  }

  update() {
    this.get();
  }
}

function observe(data) {
  Object.keys(data).forEach((key) => {
    let value = data[key];
    let dep = new Dep();
    Object.defineProperty(data, key, {
      get() {
        dep.depend();
        return value;
      },
      set(newValue) {
        value = newValue;
        dep.notify();
      },
    });
  });
}

const data = { name: "Harris", age: 26 };
observe(data);

new Watcher(() => {
  console.log("视图更新:", data.name);
});

data.name = "whxrr";

实现斐波那契数列

查看答案
js
function fibonacci(n) {
  if (n <= 1) return n;
  return fibonacci(n - 1) + fibonacci(n - 2);
}
js
function fibonacci(n, memo = {}) {
  if (n <= 1) return n;
  if (memo[n]) return memo[n];
  memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo);
  return memo[n];
}

字符串出现的不重复最长长度

查看答案
js
function longestUniqueSubstring(str) {
  let seen = new Set();
  let left = 0;
  let maxLength = 0;

  for (let right = 0; right < str.length; right++) {
    while (seen.has(str[right])) {
      seen.delete(str[left]);
      left++;
    }
    seen.add(str[right]);
    maxLength = Math.max(maxLength, right - left + 1);
  }

  return maxLength;
}

Promise 实现最大并发数

查看答案
js
function limitConcurrency(tasks, max) {
  let current = 0;
  let index = 0;
  const result = [];
  return new Promise((resolve, reject) => {
    function runNext() {
      if (index === tasks.length && current === 0) {
        return resolve(result);
      }
      while (current < max && index < tasks.length) {
        const i = index++;
        const task = tasks[i];
        current++;
        task()
          .then((res) => {
            result[i] = res;
          })
          .catch((err) => (result[i] = err))
          .finally(() => {
            current--;
            runNext();
          });
      }
    }
    runNext();
  });
}

Released under the MIT License