js中重复声明变量是否报错取决于声明方式:var同一作用域重复不报错但仅首次生效;let/const同一块级作用域重复直接报syntaxerror;严格模式不影响var/let/const重复规则,但禁用隐式全局赋值。

JS 中重复声明变量是否报错、如何处理,核心取决于声明方式(var / let / const)和执行模式(非严格模式 vs 严格模式),而不是“不同运行环境”或“浏览器版本”。关键差异不在“模式”本身,而在于声明语法的设计逻辑和引擎的解析规则。
var 声明:同一作用域内重复不报错,但仅首次生效
var 允许在同一个函数作用域或全局作用域中多次声明同名变量,后续声明会被引擎静默忽略——它不是“覆盖”,而是“不执行”。真正起作用的是第一次声明,赋值操作则独立于声明,随时可发生:
-
var a = 1; var a = 2;→ 等价于var a; a = 1; a = 2;,最终a为2 -
var b; var b = 3;→ 第二个var b被忽略,b = 3是赋值,b变为3 - 因变量提升,
console.log(a); var a = 5;输出undefined,而非报错
let 和 const 声明:块级作用域内重复直接报 SyntaxError
let 和 const 在同一块级作用域(如 {}、if 块、for 循环体)中重复声明,无论有没有赋值,都会在代码解析阶段(编译期)抛出 SyntaxError: Identifier 'x' has already been declared:
-
let x = 1; let x = 2;→ 报错,不执行 -
const y = 10; const y = 20;→ 同样报错 - 即使跨块也安全:
{ let z = 1; } { let z = 2; }合法,因属于不同块级作用域
严格模式下,隐式全局赋值会报错,但不影响 var/let/const 的重复规则
严格模式("use strict")本身不改变 var 或 let/const 的重复声明行为,但它会拦截一种常见“伪声明”错误:
- 非严格模式:
a = 100;(没用var/let/const)→ 自动创建全局变量window.a - 严格模式:
"use strict"; a = 100;→ 报ReferenceError: a is not defined - 注意:这和“重复声明”无关,而是“未声明即赋值”的容错开关被关闭了
function 声明也有重复规则,但行为特殊
函数声明(function foo() {...})在非严格模式下允许重复,后声明会覆盖前声明;严格模式下,重复函数声明在某些引擎中可能报错(非标准,但主流浏览器已趋同):
- 非严格:
function f() { return 1; } function f() { return 2; }→ 调用f()返回2 - 严格模式下,Chrome/Firefox 现在也会对重复函数声明抛
SyntaxError(ES2015+ 实践共识) - 箭头函数、函数表达式(
const f = () => {})遵循const规则,重复即报错











