在JavaScript中 let 变量的重复声明规则非常严格,默认情况下不允许重复声明 。但存在一种特殊情况:在 不同的作用域 中可以声明同名的 let 变量(这属于变量遮蔽现象)。下面详细解释:
一、let的核心规则:同一作用域内禁止重复声明
根据ES6规范 let 声明的变量具有「 不允许同一作用域内重复声明 」的特性。具体表现为:
同一代码块内 :不能用 let 重复声明已存在的变量(无论之前是用 let 、 var还是 const 声明的)。
函数作用域内 :不能用 let 重复声明函数作用域内已存在的变量。
违反此规则会直接抛 SyntaxError 错误 (语法错误,在代码解析阶段就会报错,不会执行)。
示例1:同一代码块内重复声明
{
let a = 10;
let a = 20; // 语法错误:SyntaxError: Identifier 'a' has already been declared
}示例2:与var/const在同一作用域重复声明
{
var b = 10;
let b = 20; // 语法错误:SyntaxError: Identifier 'b' has already been declared
}
{
const c = 10;
let c = 20; // 语法错误:SyntaxError: Identifier 'c' has already been declared
}二、let允许「重复声明」的唯一情况:不同作用域的变量遮蔽
let 变量 只有在不同作用域中 才可以声明同名变量,这种情况被称为「 变量遮蔽 」(Variable Shadowing)。此时,内层作用域的变量会「遮蔽」外层作用域的同名变量,但它们本质上是两个独立的变量。
示例3:不同作用域的同名let变量
// 外层作用域声明let变量
let x = 100;
function test() {
// 内层作用域可以声明同名的let变量(这不是重复声明,而是创建了新变量)
let x = 200;
console.log(x); // 输出:200(访问的是内层变量)
}
test();
console.log(x); // 输出:100(访问的是外层变量)示例4:代码块内的变量遮蔽
let y = 300;
if (true) {
let y = 400; // 内层块级作用域的y,遮蔽外层的y
console.log(y); // 输出:400
}
console.log(y); // 输出:300(外层的y不受影响)三、注意事项
变量遮蔽≠重复声明 :变量遮蔽是在不同作用域中创建同名变量,而重复声明是在同一作用域中声明已存在的变量。
严格模式与非严格模式 : let 的重复声明规则在严格模式和非严格模式下都适用(因let本身是ES6的严格特性)。
全局作用域的特殊情况 :即使在全局作用域用 let 声明的变量,也不会挂载到全局对象(如 window )上,因此不会与全局对象的属性产生冲突,但仍遵循同一作用域不重复声明的规则。
总结
let 变量 只有在不同作用域中 可以声明同名变量(变量遮蔽),而在 同一作用域内永远不允许重复声明 (会直接抛出语法错误)。这一特性是 let 相比 var 更严格的表现之一,旨在避免变量重复声明导致的逻辑混乱和潜在错误。