JS自定义Templater类函数执行顺序异常 嵌套HTML输出错误如何修复
问题根因
你遇到的输出异常是JS参数执行顺序和现有代码逻辑冲突导致的:
JS调用函数时,会先计算所有参数的值再执行函数本体。你调用template.p('123', template.span('321'))时,会先执行template.span('321'),这个方法直接把<span>321</span>追加到了全局output属性,还返回了实例对象本身。等到执行p方法时,拼接参数会把实例转成字符串(此时已经包含提前写入的span内容),再把p标签整体追加到output,最终就出现了span重复、顺序错误的问题。
修正方案
核心逻辑调整为:嵌套的子标签方法不直接修改全局output,只返回自身生成的HTML片段,仅最外层标签把最终内容写入全局output,就可以得到预期结果。
极简适配版(适配你当前的使用场景)
class Templater { constructor() { this.output = ''; } span(...tags) { const transform = tags => tags.join(''); // 嵌套用的子标签直接返回构造好的字符串,不修改全局output return `<span>${transform(tags)}</span>` } p(...tags) { const transform = tags => tags.join(''); this.output += `<p>${transform(tags)}</p>` return this; } toString() { return this.output; } } const template = new Templater(); console.log(template.p('123', template.span('321')).toString()); // 输出:<p>123<span>321</span></p>
通用兼容版(支持所有标签作为顶层/嵌套使用)
如果后续需要把span等其他标签也作为最外层调用,可以用上下文判断的通用逻辑:
class Templater { constructor() { this.output = ''; } // 通用标签生成逻辑,所有标签方法复用 #buildTag(tagName, tags) { const transform = tags => tags.join(''); return `<${tagName}>${transform(tags)}</${tagName}>`; } span(...tags) { const tagContent = this.#buildTag('span', tags); // 调用栈超过1层说明是嵌套调用,直接返回片段,不写入全局output if (new Error().stack.match(/at (span|p)/g)?.length > 1) { return tagContent; } this.output += tagContent; return this; } p(...tags) { const tagContent = this.#buildTag('p', tags); if (new Error().stack.match(/at (span|p)/g)?.length > 1) { return tagContent; } this.output += tagContent; return this; } toString() { return this.output; } }
内容的提问来源于stack exchange,提问作者Rurohi53
相关产品推荐
相关产品推荐

