You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中函数内重赋值var变量为何会作用到函数外部?

问题核心原因

你在函数内写的c = 2从来没有创建过函数作用域内的局部变量,本质是顺着作用域链修改了全局作用域下已经存在的变量c,修改结果当然会在函数外部生效。


JS变量赋值的作用域查找规则

JS引擎执行赋值语句时,会严格按照从内到外的顺序沿作用域链查找目标变量:

  • 首先检查当前函数作用域内,是否存在通过var/let/const/function声明的同名变量,如果有,就直接修改这个局部变量,不会影响外层
  • 如果当前作用域找不到,就逐层向上跳到外层作用域查找,直到全局作用域
  • 非严格模式下,如果全局作用域也找不到同名声明,才会自动在全局创建一个隐式全局变量再赋值;严格模式下这种情况会直接抛出ReferenceError,不会偷偷创建全局变量

回到你的示例代码,全局作用域一开始就通过var c = 1声明了变量c,函数Fn内部没有任何对c的声明,执行c=2时会直接找到全局的c修改值,不存在“被限制在函数作用域”的可能。


对你的猜想的纠正

你的猜想:当在函数内编写c = 2语句时,是否是JavaScript引擎自动在函数外部提升声明一个新的var c,先为其赋值undefined,待Fn()调用执行时再将值修改为2?

这个结论是错的,核心原因是你对变量提升的作用范围存在误解:
变量提升只发生在声明所在的当前作用域内,永远不会跨作用域跑到外层去新增声明。
你的代码执行的完整流程没有任何“外部新增var c”的步骤:

  1. 全局上下文预编译阶段:全局的var c声明、Fn函数声明被提升到全局作用域顶部,c初始值为undefined
  2. 全局代码逐行执行:运行到var c = 1时,全局c被赋值为1
  3. 调用Fn()进入函数上下文:预编译扫描函数内部,没有找到任何c的声明,因此函数作用域内根本不存在c这个变量绑定
  4. 函数内执行c=2:沿作用域链找到全局的c,将其值修改为2
  5. 函数执行结束弹出调用栈,全局访问c时拿到的就是修改后的值2

对比参考:如果要让赋值只在函数内生效的写法

只要在函数内部显式声明c,赋值就会被限制在函数作用域内,不会影响全局的c:

var c = 1;
function Fn() {
  // 函数内显式声明局部变量c
  var c = 2;
}
Fn();
console.log(c); // 输出1,全局变量没有被修改

内容的提问来源于stack exchange,提问作者user10869882

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 07:48:58