10、✅ 手写简易模板引擎(变量替换 + 简单循环)

73 阅读1分钟

🎯 一、为什么要掌握模板引擎?

掌握模板引擎的实现,意味着你理解了:

  • 字符串解析 + 正则处理
  • JS 动态执行函数的能力(Function 构造器)
  • 模板编译原理(Vue/React 的编译阶段核心)
  • 面试官会以此判断你是否掌握数据 → 视图的底层过程

🧠 二、我们要实现的目标

输入模板:

const template = `
  <h1>{{ title }}</h1>
  <ul>
    {{ for item in list }}
      <li>{{ item }}</li>
    {{ end }}
  </ul>
`;

输入数据:

const data = {
  title: '水果列表',
  list: ['🍎 苹果', '🍌 香蕉', '🍇 葡萄']
};

输出 HTML:

<h1>水果列表</h1>
<ul>
  <li>🍎 苹果</li>
  <li>🍌 香蕉</li>
  <li>🍇 葡萄</li>
</ul>

🧩 三、核心思想

将模板字符串编译为 JS 执行函数

function render(data) {
  return new Function('data', `with(data){ return `${compiledTemplate}`; }`)(data);
}

✍️ 四、实现步骤:简易模板引擎核心代码

function compile(template) {
  // 1. 替换 {{ xxx }} → ${xxx}
  let code = template
    .replace(/{{\s*(.*?)\s*}}/g, (_, expr) => `${${expr}}`);

  // 2. 处理 for 循环
  code = code
    .replace(/${for (.+?) in (.+?)}/g, '`; for(let $1 of $2) { output += `')
    .replace(/${end}/g, '`;} output += `');

  // 3. 生成函数体
  const finalCode = `
    let output = ``;
    with(data) {
      output += `${code}`;
    }
    return output;
  `;

  return new Function('data', finalCode);
}

✅ 使用方式:

const render = compile(template);
const result = render(data);
console.log(result);

📌 五、支持语法

语法示例功能
插值{{ title }}数据替换
for 循环{{ for item in list }}...{{ end }}遍历数组

✅ 六、测试输出结果

<h1>水果列表</h1>
<ul>
  <li>🍎 苹果</li>
  <li>🍌 香蕉</li>
  <li>🍇 葡萄</li>
</ul>

完美符合预期 ✅


🎯 七、进阶点(可拓展)

进阶功能实现建议
if 判断支持 {{ if condition }}...{{ else }}...{{ end }},同理替换为 JS
函数调用在 with(data) 作用域中可直接调用
AST 编译高级模板引擎(如 Vue)基于 AST,非必需但可了解

❗ 八、面试易错点

问题解法
模板变量取不到值使用 with(data) 注入作用域
标签嵌套错乱必须正确关闭循环、判断等逻辑块
安全问题最终执行的是 JS 代码,谨防 XSS 注入(不适合生产环境)