
本文解释为何在函数内修改全局变量后,其新值在函数外部同样生效:因为全局变量只有一个实例,赋值操作会直接改变该变量的值,而非创建局部副本。
在 JavaScript 中,变量的作用域决定了它在哪里被声明和在哪里可被访问,但并不意味着变量值会“自动复制”或“隔离更新”。关键在于:变量是否被重新声明(let/const/var),而非是否在函数内被赋值。
回到你的示例:
let num = 50;
const logNum = () => {
num = 100; // ⚠️ 没有使用 let/const,这是对全局 num 的直接赋值
console.log(num);
};
logNum(); // 输出: 100
console.log(num); // 输出: 100这里 num = 100 并未声明新变量(没有 let、const 或 var),因此 JavaScript 引擎会沿作用域链向上查找——发现外层存在一个 let num 声明(全局作用域),于是直接更新该变量的值。这不是“局部更新”,而是“全局更新”。
✅ 正确理解:
立即学习“Java免费学习笔记(深入)”;
- let num = 50 创建了一个块级作用域的全局变量(在模块顶层或脚本顶层,属于全局作用域);
- 函数内部未用 let/const 重新声明 num,因此所有对 num 的读写都指向同一个绑定;
- 变量只有一个,值只有一份——50 被覆盖为 100 后,无论从何处访问,结果都是 100。
? 对比:若想让函数内拥有独立的 num,必须显式声明:
let num = 50;
const logNum = () => {
let num = 100; // ✅ 新建局部变量(同名遮蔽 global num)
console.log(num); // 100
};
logNum();
console.log(num); // 50 ← 全局 num 未受影响这种现象称为变量遮蔽(variable shadowing):内层作用域中同名变量会暂时“遮住”外层变量,但二者内存地址不同,互不干扰。
⚠️ 注意事项:
- 避免无意遮蔽全局变量,易引发隐蔽 bug;
- 在严格模式下,对未声明变量赋值(如 unknownVar = 42)会抛出 ReferenceError,而本例因 num 已声明,故安全;
- 使用 const 声明全局配置项可防止意外重赋值,提升代码健壮性。
总结:作用域控制的是变量的可见性与生命周期,而赋值操作本身不创造新变量——除非配合声明关键字。理解“声明 vs 赋值”的本质区别,是掌握 JavaScript 作用域机制的关键一步。


















