JavaScript 中全局变量在函数内修改后为何外部值也改变?

1次阅读

JavaScript 中全局变量在函数内修改后为何外部值也改变?

本文解释 javascript 全局变量作用域与赋值行为:全局变量仅有一份内存实例,函数内对其重新赋值会直接影响全局状态,而非创建局部副本;若需局部隔离,必须显式用 `let`/`const` 在函数内重新声明同名变量。

javaScript 中,变量的作用域(scope)决定了它在哪里被定义、在哪里可被访问,但作用域不等于副本。你提供的代码中:

let num = 50;  const logNum = () => {   num = 100; // ⚠️ 没有使用 let/const 声明,这是对全局 num 的直接赋值   console.log(num); };  logNum();     // 输出 100 console.log(num); // 仍输出 100

这里 num 是在全局作用域中用 let 声明的——这意味着它是一个块级全局变量(非 var 的函数作用域,但仍是全局可访问的绑定)。当 logNum 函数执行时,num = 100 这一行并未声明新变量,而是查找当前作用域链中最近的 num 绑定。由于函数内部没有用 let num 或 const num 重新声明,js 引擎向上查找到全局作用域的 num,并将其值由 50 更新为 100。

✅ 关键点总结:

  • 一个标识符,一个绑定:num 是单一的变量绑定,无论在哪访问或修改,操作的都是同一内存位置;
  • 赋值 ≠ 重声明:num = 100 是赋值语句,不是声明语句;只有 let/const/var 开头才是声明;
  • 作用域影响“可见性”,不影响“独立性”:全局变量在函数内可见且可写(除非是 const 声明的不可重新赋值常量),写它就是在改它本身。

? 对比:如何实现“函数内修改不影响外部”?
只需在函数内显式声明同名局部变量,从而屏蔽(shadow)全局变量:

let num = 50;  const logNum = () => {   let num = 50; // ✅ 新建局部变量,与全局 num 无关   num = 100;   console.log(num); // 100 };  logNum(); console.log(num); // 50 ← 全局 num 未受影响

⚠️ 注意事项:

立即学习Java免费学习笔记(深入)”;

  • 避免隐式全局(如直接写 num = 100 而未声明),尤其在严格模式下会报错;
  • 同名变量遮蔽(variable shadowing)虽合法,但易引发维护困惑,建议用语义化不同名(如 localCount / globalThreshold);
  • 若需真正隔离状态,优先考虑函数参数传入、返回新值,或使用闭包封装私有数据。

理解“声明”与“赋值”的本质区别,是掌握 javascript 作用域机制的关键一步。

text=ZqhQzanResources