javascript中不存在“作用域提升”,只有变量提升和函数提升;函数声明优先于var变量声明被提升,但赋值仍按原位置执行;函数表达式仅变量名提升,赋值不提升;let/const无提升且同名直接报错。

JavaScript 中没有“作用域提升”这个概念,真正发生的是 变量提升(hoisting) 和 函数提升,它们都发生在代码执行前的预处理阶段,并且严格按声明类型和优先级处理同名标识符。
同名变量与函数声明:函数声明优先覆盖
当 var 变量声明和函数声明使用相同名称时,函数声明会完整提升到作用域顶部,变量声明被忽略(不重复提升),但后续的变量赋值仍会生效。
- 函数声明(
function foo() {})整体提升,包括函数体 -
var foo声明被跳过——因为同名函数已存在,引擎不再为它创建新绑定 -
foo = 'bar'是普通赋值操作,发生在原位置,会覆盖之前提升的函数值
示例:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
console.log(foo); // function foo() {}
function foo() { console.log('I am function'); }
var foo = 'I am string';
console.log(foo); // "I am string"
foo(); // TypeError: foo is not a function
函数表达式不享受函数提升,只按变量规则处理
用 var foo = function() {} 这种方式定义的,本质是变量声明 + 匿名函数赋值。只有 var foo 被提升,赋值部分保留在原地。
- 调用
foo()在声明前 →TypeError: foo is not a function(因为此时 foo 是 undefined) - 即使上方有同名函数声明,也会被后续的变量赋值覆盖
示例:
foo(); // TypeError: foo is not a function
var foo = function() { console.log('expr'); };
function foo() { console.log('decl'); }
let/const 不提升,同名会直接报错
let 和 const 声明不存在提升,也不允许重复声明。若与函数声明同名,会触发语法错误(SyntaxError),在解析阶段就失败,不会进入执行。
-
let foo = 1; function foo() {}→ 报错:“Identifier 'foo' has already been declared” - 这与 var 的“静默覆盖”完全不同,是更严格的约束
实际编码建议
- 避免函数名与变量名冲突,尤其在同一个作用域内
- 优先使用
const或let,天然规避 hoisting 引发的歧义 - 函数尽量用声明形式(
function name() {})确保可提前调用;需延迟初始化时,明确用函数表达式并控制调用时机 - 调试时遇到
undefined或TypeError,先检查是否因同名覆盖导致类型意外变更
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










