一、块级作用域与 let / const
✅ ES6 引入了块级作用域
- 使用
{} 创建一个独立的作用域。
- 在这个作用域中使用
let 和 const 声明的变量只在该作用域内有效。
✅ 暂时性死区(Temporal Dead Zone, TDZ)
- 定义:在代码块内,使用
let 或 const 声明变量之前,该变量处于“暂时性死区”,不可访问。
- 本质:变量已经在作用域中存在,但尚未初始化,因此不能访问。
- 示例:
typeof x;
let x;
⚠️ typeof 不再是安全操作
二、块级作用域中的函数声明
✅ ES6 允许在块级作用域中声明函数
{
function foo() {
return 1;
}
console.log(foo());
}
console.log(foo());
- 函数只在当前块级作用域中有效。
- 行为类似于
let,不会泄漏到外部。
⚠️ 浏览器环境 vs 非浏览器环境(如 Node.js)
| 环境 | 行为说明 |
|---|
| 浏览器 | 函数声明会被提升到全局或函数作用域顶部,类似 var |
| Node.js 等非浏览器环境 | 函数声明行为更像 let,存在 TDZ,不能在声明前访问 |
示例对比
if (true) {
foo();
function foo() { return 'A'; }
}
💡 实际开发建议
- 避免在块级作用域中声明函数,尤其是需要跨块使用的情况。
- 如果必须使用,推荐使用函数表达式:
{
const bar = function () {
console.log("safe");
};
}
三、严格模式下的函数声明限制
✅ 允许在块级作用域中声明函数的前提是:必须有大括号 {} 包裹
'use strict';
if (true) {
function foo() {}
}
❌ 非法写法:没有 {},语法错误
'use strict';
if (true)
function foo() {}
📌 原因
- 在严格模式下,函数声明只能出现在当前作用域的顶层或由
{} 构成的块级作用域内部。
- 控制流语句(如
if, while)后直接跟函数声明是不被允许的。
四、总结 & 小贴士
| 项目 | 内容 |
|---|
| ✅ 块级作用域 | 通过 {} 创建,用 let/const 声明的变量只在该作用域中有效 |
| ⚠️ 暂时性死区 | 变量已存在但未初始化,不能访问,否则报错 |
⚠️ typeof 安全性下降 | 对于 TDZ 中的变量,也会报错 |
| ⚠️ 函数声明行为不一致 | 浏览器中类似 var,其他环境类似 let |
| ✅ 推荐写法 | 使用函数表达式代替函数声明 |
| 🔒 严格模式限制 | 控制流语句后不能直接写函数声明,必须用 {} 包裹 |
🧠 总结一句话
ES6 引入了块级作用域和暂时性死区,提升了变量控制的安全性和灵活性,但也带来了函数声明行为的复杂性和环境差异。为了代码的可读性和一致性,应优先使用函数表达式,并注意严格模式下的语法限制。