如何在JavaScript模板字面量标签函数中获取插值变量名?
核心结论
原生JS的标签模板函数运行时无法直接获取插值的变量名,也拿不到完整的未解析原始模板字符串,这是JS语言本身的机制决定的。
原因说明
JS引擎解析标签模板时,会在调用你的html函数前提前完成两步处理:
- 把模板里所有静态文本部分拆分出来,组成你拿到的
literals数组,所有${}包裹的插值位置都会被挖空,你从literals.raw里只能拿到拆分后的片段,拼不回带原始${xxx}标记的完整模板 - 对所有
${}里的表达式提前求值,你拿到的vars数组只是求值后的结果值,和表达式本身、用到的变量名没有任何关联。比如你写${count + 1},你拿到的就是计算后的数值,根本不知道这个值是怎么算出来的,更提取不到count这个变量名。
拿你写的示例来说,引擎实际传给html的参数等价于:
html.call(undefined, ['<h3>Count: ', '</h3>'], 0)
没有任何额外元信息会被传入。
可行实现方案
如果一定要拿到这两个信息,只能走编译期预处理的路线,不要指望运行时原生能力:
- 写一个Babel/SWC/Rollup/Vite的编译插件,在代码构建阶段扫描所有
html标签模板的调用点,提前提取出完整的原始模板字符串、每个插值位置的表达式文本,作为额外参数注入到函数调用里。
举个例子,编译前的代码:
编译后可以被插件转换成:const count = 0; html`<h3>Count: ${count}</h3>`;
这样你在const count = 0; html( ['<h3>Count: ', '</h3>'], 0, { rawTemplate: '<h3>Count: ${count}</h3>', expressions: ['count'] } );html函数里直接读第三个参数,就能拿到你要的原始模板串和插值变量名了。现在主流的带模板编译能力的库(比如lit的部分扩展、各类类JSX模板库)都是用的这个方案。 - 不要用运行时取调用栈、读源码文件解析这类方案:这类方案性能极差,而且生产环境代码压缩混淆后,变量名、代码格式都会改变,解析结果完全不可靠。
内容的提问来源于stack exchange,提问作者inux
相关产品推荐
相关产品推荐

