返回

前端面试手撕JS高频考点

前端

前言

前端面试中,手撕代码显然是不可避免的,占很大的一部分比重。本文涵盖了前端面试常见的各种手写题目,大部分都是自己找实习、秋招时遇到的。希望能对各位前端er有所帮助。

正则表达式

  1. 实现一个函数,判断一个字符串是否为回文串。
function isPalindrome(str) {
  if (!str || str.length === 0) {
    return true;
  }

  // 去掉字符串中的空格和标点符号
  str = str.replace(/[\s+\W]/g, "").toLowerCase();

  // 将字符串反转
  const reversedStr = str.split("").reverse().join("");

  // 比较原字符串和反转后的字符串是否相等
  return str === reversedStr;
}
  1. 实现一个函数,提取字符串中的数字。
function extractNumbers(str) {
  // 使用正则表达式提取字符串中的数字
  const numbers = str.match(/\d+/g);

  // 将数字数组转换为数字类型
  const numbersAsInts = numbers.map(Number);

  // 返回数字数组
  return numbersAsInts;
}

数组

  1. 实现一个函数,判断一个数组是否包含重复的元素。
function hasDuplicates(arr) {
  // 使用 Set 数据结构来存储数组中的元素
  const set = new Set();

  // 遍历数组中的元素
  for (let i = 0; i < arr.length; i++) {
    // 如果元素已经存在于 Set 中,则说明数组中存在重复元素
    if (set.has(arr[i])) {
      return true;
    }

    // 将元素添加到 Set 中
    set.add(arr[i]);
  }

  // 如果 Set 中没有重复元素,则数组中也没有重复元素
  return false;
}
  1. 实现一个函数,将一个数组中的所有元素翻转。
function reverseArray(arr) {
  // 使用 Array.reverse() 方法翻转数组
  const reversedArr = arr.reverse();

  // 返回翻转后的数组
  return reversedArr;
}

链表

  1. 实现一个函数,反转一个单链表。
function reverseLinkedList(head) {
  // 定义一个变量 prev 来存储上一个节点
  let prev = null;

  // 定义一个变量 curr 来存储当前节点
  let curr = head;

  // 遍历链表
  while (curr) {
    // 将当前节点的 next 指向 prev
    curr.next = prev;

    // 将 prev 指向当前节点
    prev = curr;

    // 将 curr 指向下一个节点
    curr = curr.next;
  }

  // 返回翻转后的链表的头节点
  return prev;
}
  1. 实现一个函数,判断一个单链表是否有环。
function hasCycle(head) {
  // 定义两个指针,slow 和 fast
  let slow = head;
  let fast = head;

  // 遍历链表
  while (fast && fast.next) {
    // 慢指针每次移动一步
    slow = slow.next;

    // 快指针每次移动两步
    fast = fast.next.next;

    // 如果慢指针和快指针相遇,则说明链表有环
    if (slow === fast) {
      return true;
    }
  }

  // 如果慢指针和快指针没有相遇,则说明链表没有环
  return false;
}

  1. 实现一个函数,判断一棵二叉树是否是二叉搜索树。
function isBinarySearchTree(root) {
  // 定义一个辅助函数来判断子树是否是二叉搜索树
  function isBST(node, min, max) {
    // 如果节点为空,则返回 true
    if (!node) {
      return true;
    }

    // 如果节点的值小于或等于 min,则返回 false
    if (node.val <= min) {
      return false;
    }

    // 如果节点的值大于或等于 max,则返回 false
    if (node.val >= max) {
      return false;
    }

    // 如果节点的值在 min max 之间,则递归检查左子树和右子树是否都是二叉搜索树
    return isBST(node.left, min, node.val) && isBST(node.right, node.val, max);
  }

  // 从根节点开始检查
  return isBST(root, Number.MIN_VALUE, Number.MAX_VALUE);
}
  1. 实现一个函数,找到一棵二叉树的最大深度。
function maxDepth(root) {
  // 如果根节点为空,则返回 0
  if (!root) {
    return 0;
  }

  // 计算左子树的深度
  const leftDepth = maxDepth(root.left);

  // 计算右子树的深度
  const rightDepth = maxDepth(root.right);

  // 返回左右子树中较大的深度加 1
  return Math.max(leftDepth, rightDepth) + 1;
}

算法

  1. 实现一个函数,计算两个数字的最大公约数。
function gcd(a, b) {
  // 如果 b 为 0,则返回 a
  if (b === 0) {
    return a;
  }

  // 递归调用 gcd(b, a % b)
  return gcd(b, a % b);
}
  1. 实现一个函数,计算两个数字的最小公倍数。
function lcm(a, b) {
  // 计算两个数字的最大公约数
  const gcdValue = gcd(a, b);

  // 计算最小公倍数
  const lcmValue = (a * b) / gcdValue;

  // 返回最小公倍数
  return lcmValue;
}

前端工程化

  1. 实现一个函数,判断一个字符串是否为有效的 JSON 字符串。
function isValidJSON(str) {
  try {
    // 尝试解析字符串为 JSON 对象
    const json = JSON.parse(str);

    // 如果解析成功,则返回 true
    return true;
  } catch (err) {
    // 如果解析失败,则返回 false
    return false;
  }
}
  1. 实现一个函数,将一个对象转换为 JSON 字符串。
function stringifyJSON(obj) {
  // 使用 JSON.stringify() 方法将对象转换为 JSON 字符串
  const json = JSON.stringify(obj);

  // 返回 JSON 字符串
  return json;
}

结语

以上只是前端面试中常见手写题目的冰山一角。要想在面试中取得好的成绩,还需要多加练习,积累更多的经验。希望本文能对各位前端er有所帮助,祝大家都能找到一份好工作!