前端面试手撕代码(字节)

前端面试手撕代码(字节)

字节一面给了两道手撕代码,还是比较偏向场景,不是leetcode那种逻辑题。

题目一:实现 Compile 函数

这是一道经典的前端面试题,一般面试中如果你提到框架原理,面试官都会想到这道题。 之前拼多多面试也考了,但是比这个复杂,要求还要渲染对象中的数组juejin.cn/post/747562...

题目要求

将模板字符串中的插值(如 {{user.name}})编译为具体的值。例如,输入模板 "Hello, {{user.name}}!" 和数据 {user: {name: "Alice"}},输出 "Hello, Alice!"

实现思路
  1. 正则匹配插值 :使用正则表达式(如 /\{\{([^}]+)\}\}/g)定位模板中的插值表达式,提取变量路径(如 user.name)。
  2. 数据路径解析 :将变量路径按 . 分割为层级数组(如 ["user", "name"]),逐层访问数据对象的属性。

代码示例

javascript 复制代码
function compile(template) {
  const regex = /\{\{([^}]+)\}\}/g;
  return function(data) {
    return template.replace(regex, (match, path) => {
      const keys = path.trim().split('.');
      return keys.reduce((obj, key) => obj?.[key], data) || '';
    });
  };
}

// 使用示例
const template = "Hello, {{user.name}}! Age: {{age}}";
const render = compile(template);
console.log(render({ user: { name: "Alice" }, age: 25 })); 
// 输出: "Hello, Alice! Age: 25"

优化点

缓存正则表达式 :避免重复创建正则对象提升性能。

处理深层嵌套 :通过 reduce 逐层安全访问属性,避免因路径错误导致的报错。

法二:使用with函数实现
javascript 复制代码
function compile(template, context) {
  // 替换模板中的插值表达式为 JavaScript 模板字符串语法
  const compiledTemplate = template.replace(
    /{{(.*?)}}/g,
    (match, p1) => `\${${p1.trim()}}`
  );

  // 动态生成一个函数,用于替换模板中的插值表达式
  const compiledFunction = new Function(
    "context",
    `
    with (context) {
      return \`${compiledTemplate}\`;
    }
  `
  );

  // 调用函数并返回结果
  return compiledFunction(context);
}



const template =
  "Hello, ${user.name}! Your balance is${user.balance}. You have ${user.items[0]} in your cart. and${user.items[2].kk}";
const exprObj = {
  user: {
    name: "Alice",
    balance: 100.5,
    items: ["Item1", "Item2", { kk: 1 }],
  },
};
const compiledString = compile(template, exprObj);
console.log(compiledString);

使用with函数是非常取巧的,不仅代码少,而且处理了所有情况,面试如果想要快速实现,可以使用第法二。


题目二:树形菜单渲染

题目要求

给定树形结构数据,将其渲染为 HTML 菜单,并支持点击展开/收起子节点。例如输入:

javascript 复制代码
const treeData = [
  {
    "id": 1,
    "parent_id": 0,
    "name": "北京",
    "children": [
      {
        "id": 3,
        "parent_id": 1,
        "name": "海淀区",
        "children": []
      },
      {
        "id": 4,
        "parent_id": 1,
        "name": "朝阳区",
        "children": []
      }
    ]
  }
];

输出可交互的树形菜单,点击父节点时切换子节点的显示状态。


完整实现方案

以下代码通过 DOM 操作事件绑定实现动态渲染与交互:

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Tree Directory Component</title>
  <style>
    .tree-node { cursor: pointer; margin-left: 20px; }
    .children { display: none; margin-left: 20px; } /* 默认隐藏子节点 */
  </style>
</head>
<body>
  <div id="tree"></div>
  <script>
    const treeData = [/* 此处省略,结构与上文一致 */];

    // 递归创建树节点
    function createTreeNode(node, parentElement) {
      const div = document.createElement('div');
      div.className = 'tree-node';
      div.textContent = node.name;
      
      // 点击事件:切换子节点显隐
      div.onclick = function() {
        const childrenDiv = parentElement.querySelector('.children');
        if (childrenDiv) {
          childrenDiv.style.display = 
            childrenDiv.style.display === 'none' ? 'block' : 'none';
        }
      };
      
      parentElement.appendChild(div);

      // 递归处理子节点
      if (node.children?.length) {
        const childrenDiv = document.createElement('div');
        childrenDiv.className = 'children';
        node.children.forEach(child => createTreeNode(child, childrenDiv));
        parentElement.appendChild(childrenDiv);
      }
    }

    // 渲染根节点
    const treeElement = document.getElementById('tree');
    treeData.forEach(node => createTreeNode(node, treeElement));
  </script>
</body>
</html>

代码解析
  1. HTML 结构

    • 仅需一个 <div id="tree"> 容器,所有节点通过 JavaScript 动态生成。

    • 样式通过 CSS 类名控制(.tree-node 定义节点样式,.children 控制子节点缩进与显隐)。

  2. 核心逻辑

    递归构建节点createTreeNode 函数递归生成 <div> 元素,每个节点绑定 onclick 事件。

    事件处理 :点击父节点时,通过 querySelector 查找子容器,切换其 display 属性实现展开/收起。

    DOM 操作优化:直接操作 DOM 元素而非拼接字符串,便于动态更新和事件绑定。

  3. 交互扩展思路

    动画效果 :添加 CSS transition 属性实现平滑展开效果。

    懒加载 :点击父节点时动态请求子节点数据(需后端配合)。

    多选/折叠 :通过 dataset 属性标记节点状态,实现全选或折叠全部子节点。


总结

字节一面考察的两道题都是经典的场景题,因该是面试中问到了vue的原理,所以顺带考了compile和render的题。

相关推荐
YeeWang31 分钟前
🎉 Eficy 让你的 Cherry Studio 直接生成可预览的 React 页面
前端·javascript
gnip33 分钟前
Jenkins部署前端项目实战方案
前端·javascript·架构
地平线开发者1 小时前
征程 6 | PTQ 精度调优辅助代码,总有你用得上的
算法·自动驾驶
Orange3015111 小时前
《深入源码理解webpack构建流程》
前端·javascript·webpack·typescript·node.js·es6
lovepenny1 小时前
Failed to resolve entry for package "js-demo-tools". The package may have ......
前端·npm
Tisfy1 小时前
LeetCode 837.新 21 点:动态规划+滑动窗口
数学·算法·leetcode·动态规划·dp·滑动窗口·概率
超凌1 小时前
threejs 创建了10w条THREE.Line,销毁数据,等待了10秒
前端
车厘小团子2 小时前
🎨 前端多主题最佳实践:用 Less Map + generate-css 打造自动化主题系统
前端·架构·less
慧翔天地人才发展学苑2 小时前
大厂 | 华为半导体业务部2026届秋招启动
华为·面试·职场和发展·跳槽·求职招聘·职场晋升
芒果1252 小时前
SVG图片通过img引入修改颜色
前端