应优先用模板字符串定骨架、join()聚合动态内容,避免重复创建中间字符串;需预转义防XSS;复杂结构宜封装为纯函数再join。

直接用 join() 拼接字符串再插入模板字符串,性能反而更差——关键在于避免重复创建中间字符串,优先让模板字符串承担结构职责,join() 只负责高效聚合动态内容。
模板字符串定骨架,join() 填数据块
把静态 HTML 结构写在模板字符串里,只把需要循环生成的、同类的标签片段交给 join() 处理。这样模板字符串只执行一次解析,join() 在底层用连续内存拼接,比多次 += 或嵌套模板快得多。
例如生成一列带 class 的按钮:
const labels = ['保存', '取消', '删除'];
const html = `
<div class="btn-group">
${labels.map(label => `<button class="btn">${label}</button>`).join('')}
</div>
`;
这里 map() 生成数组,join('') 一次性拼成完整内嵌 HTML,外层模板不参与循环,无重复解析开销。
立即学习“前端免费学习笔记(深入)”;
预转义内容再 join,避免 XSS 风险
join() 不处理转义,直接拼接用户输入会引发 XSS。必须先对每个动态值做 HTML 实体转义,再交给 join()。
推荐轻量函数:
const escape = str => str .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, '"') .replace(/'/g, ''');
使用时:
const items = ['<script>alert(1)</script>', 'Hello & World'];
const listHtml = items
.map(item => `<li>${escape(item)}</li>`)
.join('');
const html = `<ul>${listHtml}</ul>`;
复杂结构用函数封装,保持可读性
当 HTML 片段含多层嵌套或条件逻辑,别硬塞进一行模板。把每类子结构封装成纯函数,返回已拼好的字符串,再用 join() 组合。
例如渲染带图标的菜单项:
const renderMenuItem = ({ label, icon, disabled }) =>
`<li class="${disabled ? 'disabled' : ''}">
<span class="icon">${icon}</span>
<span class="label">${escape(label)}</span>
</li>`;
const menuItems = [
{ label: '设置', icon: '⚙️', disabled: false },
{ label: '帮助', icon: '❓', disabled: true }
];
const menuHtml = `
<ul class="menu">
${menuItems.map(renderMenuItem).join('')}
</ul>
`;
注意:不要在 join() 中混用模板字符串变量
下面写法是反模式:
// ❌ 错误:每次 map 都新建模板字符串,失去 join 优势
items.map(item => `${prefix}<div>${item}</div>${suffix}`).join('')
应改为:
// ✅ 正确:静态部分提至模板外,join 只处理纯数据映射
const inner = items.map(item => `<div>${escape(item)}</div>`).join('');
const html = `${prefix}${inner}${suffix}`;



















