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

JavaScript变量提升与执行上下文:为何代码输出为'abc123'而非'123bcd'

问题拆解:为什么全局变量没被覆盖?

嘿,这个问题的核心就是**变量提升(hoisting)**在函数作用域里的表现,咱们一步步拆解你的代码就能明白啦!

首先先把你的代码贴出来方便分析:

var employeeId = 'abc123'; 
function foo() { 
  employeeId = '123bcd'; 
  return; 
  var employeeId = function(){} 
} 
foo(); 
console.log(employeeId); // 输出 'abc123'

第一步:全局执行上下文的初始化

在代码开始执行前,全局执行上下文会先处理所有的var声明和函数声明:

  • var employeeId被提升到全局作用域顶部,初始值为undefined,之后代码执行到var employeeId = 'abc123'时,才会把值赋值给它。
  • function foo整个函数声明也被提升到全局作用域,所以后面可以直接调用foo()。

第二步:进入foo函数的执行上下文

当调用foo()时,JavaScript会创建一个新的函数执行上下文,这一步最关键的是变量提升的优先级:
不管var声明写在函数的哪个位置(哪怕是return之后),它都会被提升到当前函数作用域的顶部,并且初始化为undefined。

所以你的foo函数在执行时,实际等价于下面的代码:

function foo() {
  var employeeId; // 变量提升到函数顶部,属于局部作用域
  employeeId = '123bcd'; // 这里赋值的是局部的employeeId,不是全局的!
  return; // 直接退出函数,后面的代码根本不会执行
  employeeId = function(){}; // 这行永远不会被执行
}

看到了吧?你原本以为employeeId = '123bcd'操作的是全局变量,但实际上因为函数内部的var employeeId被提升了,这个employeeId已经是函数的局部变量了,和全局的employeeId完全是两个独立的变量。

第三步:函数执行完毕,全局变量未被修改

当foo()执行完退出后,局部的employeeId就被销毁了,全局的employeeId自始至终都没被修改过,所以最后console.log(employeeId)输出的还是最初的'abc123'。

额外补充:如果去掉函数内的var employeeId会怎样?

如果把foo里的var employeeId = function(){} 删掉,那employeeId = '123bcd'就会操作全局变量,此时console.log就会输出'123bcd'了——这也是你最初预期的结果,但因为有了var声明的变量提升,结果就不一样啦!

内容的提问来源于stack exchange,提问作者chen.w

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:28:09