返回

JS手写代码:面试必备15题,轻松应对求职挑战

前端

在激烈的求职市场中,掌握JS手写代码技巧是程序员面试中的必备技能。本文从众多面试真题中,精选总结了15个常见且需要深入理解的JS手写代码题型,帮助求职者快速掌握核心考点,在面试中游刃有余。

1. 实现call()方法

call()方法允许我们为某个对象调用一个函数,并传入新的this值。

Function.prototype.myCall = function(context, ...args) {
  context.fn = this;
  context.fn(...args);
  delete context.fn;
};

2. 实现apply()方法

apply()方法与call()类似,但它接收一个参数数组,而不是一个参数列表。

Function.prototype.myApply = function(context, args) {
  context.fn = this;
  context.fn(...args);
  delete context.fn;
};

3. 实现bind()方法

bind()方法返回一个新的函数,该函数在每次调用时都会绑定到指定的this值。

Function.prototype.myBind = function(context, ...args) {
  const fn = this;
  return function(...newArgs) {
    return fn.apply(context, [...args, ...newArgs]);
  };
};

4. 实现new

new关键字创建一个新的对象,并使用构造函数来初始化该对象。

function myNew(fn, ...args) {
  const obj = {};
  Object.setPrototypeOf(obj, fn.prototype);
  const result = fn.apply(obj, args);
  return typeof result === "object" ? result : obj;
}

5. 实现Promise

Promise是一个表示异步操作最终完成或失败的JS对象。

class MyPromise {
  constructor(executor) {
    this.state = "pending";
    this.result = null;
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

    const resolve = (value) => {
      if (this.state !== "pending") return;
      this.state = "fulfilled";
      this.result = value;
      this.onFulfilledCallbacks.forEach((cb) => cb(value));
    };

    const reject = (reason) => {
      if (this.state !== "pending") return;
      this.state = "rejected";
      this.result = reason;
      this.onRejectedCallbacks.forEach((cb) => cb(reason));
    };

    executor(resolve, reject);
  }

  then(onFulfilled, onRejected) {
    if (typeof onFulfilled !== "function") onFulfilled = (value) => value;
    if (typeof onRejected !== "function") onRejected = (reason) => reason;

    return new MyPromise((resolve, reject) => {
      const fulfilled = (value) => {
        setTimeout(() => {
          try {
            const result = onFulfilled(value);
            resolve(result);
          } catch (error) {
            reject(error);
          }
        }, 0);
      };

      const rejected = (reason) => {
        setTimeout(() => {
          try {
            const result = onRejected(reason);
            resolve(result);
          } catch (error) {
            reject(error);
          }
        }, 0);
      };

      if (this.state === "fulfilled") {
        fulfilled(this.result);
      } else if (this.state === "rejected") {
        rejected(this.result);
      } else {
        this.onFulfilledCallbacks.push(fulfilled);
        this.onRejectedCallbacks.push(rejected);
      }
    });
  }

  catch(onRejected) {
    return this.then(null, onRejected);
  }
}

6. 实现instanceof操作符

instanceof操作符检查一个对象是否是某个类的实例。

function myInstanceOf(obj, Class) {
  while (obj !== null) {
    if (obj === Class.prototype) return true;
    obj = Object.getPrototypeOf(obj);
  }
  return false;
}

7. 实现深拷贝

深拷贝创建一个对象的完全独立副本,不会与原始对象共享任何引用。

function myDeepCopy(obj) {
  if (typeof obj !== "object" || obj === null) return obj;
  if (obj instanceof Date) return new Date(obj);
  if (obj instanceof RegExp) return new RegExp(obj);

  const newObj = Array.isArray(obj) ? [] : {};
  for (const key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = myDeepCopy(obj[key]);
    }
  }
  return newObj;
}

8. 实现数组去重

数组去重删除数组中重复的元素。

function myUniq(arr) {
  const seen = {};
  const newArr = [];
  for (let i = 0; i < arr.length; i++) {
    if (!seen[arr[i]]) {
      newArr.push(arr[i]);
      seen[arr[i]] = true;
    }
  }
  return newArr;
}

9. 实现数组扁平化

数组扁平化将嵌套数组展平为一维数组。

function myFlatten(arr) {
  const newArr = [];
  for (let i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      newArr.push(...myFlatten(arr[i]));
    } else {
      newArr.push(arr[i]);
    }
  }
  return newArr;
}

10. 实现斐波那契数列

斐波那契数列是一个数字序列,其中每个数字是前两个数字之和。

function myFibonacci(n) {
  if (n <= 1) return n;
  return myFibonacci(n - 1) + myFibonacci(n - 2);
}

11. 实现二分查找

二分查找是一种在有序数组中快速查找元素的算法。

function myBinarySearch(arr, target) {
  let low = 0;
  let high = arr.length - 1;
  while (low <= high) {
    const mid = Math.floor((low + high) / 2);
    if (arr[mid] === target) return mid;
    else if (arr[mid] < target) low = mid + 1;
    else high = mid - 1;
  }
  return -1;
}

12. 实现快速排序

快速排序是一种高效的排序算法,基于分治思想。

function myQuickSort(arr) {
  if (arr.length <= 1) return arr;

  const pivot = arr[0];
  const left = [];
  const right = [];

  for (let i = 1; i < arr.length; i++) {
    if (arr[i] < pivot) left.push(arr[i]);
    else right.push(arr[i]);
  }

  return [...myQuickSort(left), pivot, ...myQuickSort(right)];
}

13. 实现冒泡排序

冒泡排序是一种简单的排序算法,通过不断比较和交换相邻元素来排序。

function myBubbleSort(arr) {
  for (let i = 0; i < arr.length - 1; i++) {
    for (let j = 0; j < arr.length - 1 - i; j++) {
      if (arr[j] > arr[j + 1]) {
        [arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];
      }
    }
  }
  return arr;
}

14. 实现选择排序

选择排序是一种简单的排序算法,通过不断找到最小元素并将其与当前元素交换来排序。

function mySelectionSort(arr) {
  for (let i = 0; i < arr.length - 1; i++) {