模板字符串的嵌入表达式遵循词法作用域规则,直接访问定义位置可见的变量:可读取外层闭包、函数参数、局部变量及全局变量;不创建新作用域,不受调用栈影响;受TDZ限制,let/const声明前引用报错,var则得undefined;支持任意合法表达式,作用域由定义位置而非执行位置决定。

模板字符串内的嵌入表达式(${...})直接使用当前作用域的变量,无需额外操作——它天然支持词法作用域,和普通 JavaScript 表达式完全一致。
模板字符串中的变量来自外层词法作用域
只要变量在模板字符串定义的位置「可见」,就能直接引用。它不创建新作用域,也不受函数调用栈影响,只看书写时的嵌套位置。
- 在函数内写的模板字符串,可访问该函数的参数、局部变量、外层闭包变量
- 在全局作用域写的,可访问全局变量(包括
var声明或隐式挂载到window的变量) - 不能访问「运行时才存在」但书写时不可见的变量(比如其他函数内部的
let变量)
注意块级作用域与声明提升的区别
let 和 const 有暂时性死区(TDZ),即使在同个块中,若模板字符串写在声明之前,会报 ReferenceError。
例如:
立即学习“Java免费学习笔记(深入)”;
console.log(`${x}`); // ReferenceError: Cannot access 'x' before initialization
let x = 42;
而 var 会被提升,但值为 undefined:
console.log(`${y}`); // "undefined"
var y = 100;
函数调用或对象属性访问也照常工作
嵌入表达式里可以写任意合法表达式,包括调用当前作用域的函数、访问对象属性、三元运算等:
-
`${getName()}`→ 调用当前作用域中定义的getName函数 -
`${user.name || '匿名'}`→ 使用当前作用域的user对象 -
`${items.length > 0 ? '有数据' : '空'}`→ 完全支持逻辑判断
箭头函数与普通函数不影响模板字符串的作用域获取
模板字符串本身不改变作用域链;真正影响变量可见性的,是它「被定义的位置」,而不是「在哪里执行」。
例如:
立即学习“Java免费学习笔记(深入)”;
function outer() {
const msg = 'hello';
return () => `${msg} world`; // ✅ 正确:模板字符串定义在 outer 内,能捕获 msg
}
const fn = outer();
fn(); // "hello world"
但如果把模板字符串移到外部函数中定义,就无法访问 msg:
function outer() {
const msg = 'hello';
return getTemplate(); // ❌ 模板字符串在全局定义,看不到 msg
}
function getTemplate() {
return `${msg} world`; // ReferenceError
}


















