const 和 let 变量阴影在 switch 语句中
const and let variable shadowing in a switch statement
我有以下代码。唯一有趣的部分是我在第二个 switch case 中重新声明了 productId
。
let productId = 1;
const check = true;
switch (check) {
case false:
console.log(productId);
break;
case true:
let productId = 2;
console.log(productId);
break;
}
如果我将 check
设置为 true
,则代码可以正常工作并打印
2
如果我将 check
设置为 false
,则代码会给出 ReferenceError
/home/osama/workspace/test/javascript.js:7
console.log(productId);
^
ReferenceError: productId is not defined
at Object.<anonymous> (/home/osama/workspace/test/javascript.js:7:21)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
如果我使用 var
来声明 productId
那么无论 check
.
的值如何,代码都可以正常工作
我意识到 let/const
语句以某种方式隐藏了全局变量,但我的问题是:
为什么在 switch 语句中声明变量会导致全局变量变为未定义并抛出 ReferenceError
?
错误出现是因为你定义变量productId
两次(在switch语句之前和第二种情况中)
let productId = 1;
const check = true;
switch (check) {
case false:
console.log(productId);
break;
case true:
productId = 2; // <-- remove the let keyword on this line, the var is already defined
console.log(productId);
break;
}
您在 switch
块中有一个 let
声明。这样的声明有点像 "semi-hoisted"。它们不像 var
那样工作,但 switch
块中的符号 productId
基本上由第二个 case
中的声明声明。因此,外部 productId
被遮蔽了。
如果将第二种情况的代码包装在 { }
中,它可以正常工作。
switch (check) {
case false:
console.log(productId);
break;
case true: {
let productId = 2;
console.log(productId);
break;
}
}
在切换之前声明变量prodctId。像这样:
const check = true;
let productId;
switch(check) {
case false:
console.log(productId);
break;
case true:
productId = 2;
console.log(productId);
break;
}
提升和临时死区!
let
和 const
被提升到最近的方块,所以它变成这样:
switch (check) {
let productId;
case false:
console.log(productId);
break;
case true:
productId = 2;
console.log(productId);
break;
}
因此由于 temporal dead zone
,出现 ReferenceError
我有以下代码。唯一有趣的部分是我在第二个 switch case 中重新声明了 productId
。
let productId = 1;
const check = true;
switch (check) {
case false:
console.log(productId);
break;
case true:
let productId = 2;
console.log(productId);
break;
}
如果我将 check
设置为 true
,则代码可以正常工作并打印
2
如果我将 check
设置为 false
,则代码会给出 ReferenceError
/home/osama/workspace/test/javascript.js:7
console.log(productId);
^
ReferenceError: productId is not defined
at Object.<anonymous> (/home/osama/workspace/test/javascript.js:7:21)
at Module._compile (internal/modules/cjs/loader.js:778:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
at Module.load (internal/modules/cjs/loader.js:653:32)
at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
at Function.Module._load (internal/modules/cjs/loader.js:585:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:831:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
如果我使用 var
来声明 productId
那么无论 check
.
我意识到 let/const
语句以某种方式隐藏了全局变量,但我的问题是:
为什么在 switch 语句中声明变量会导致全局变量变为未定义并抛出 ReferenceError
?
错误出现是因为你定义变量productId
两次(在switch语句之前和第二种情况中)
let productId = 1;
const check = true;
switch (check) {
case false:
console.log(productId);
break;
case true:
productId = 2; // <-- remove the let keyword on this line, the var is already defined
console.log(productId);
break;
}
您在 switch
块中有一个 let
声明。这样的声明有点像 "semi-hoisted"。它们不像 var
那样工作,但 switch
块中的符号 productId
基本上由第二个 case
中的声明声明。因此,外部 productId
被遮蔽了。
如果将第二种情况的代码包装在 { }
中,它可以正常工作。
switch (check) {
case false:
console.log(productId);
break;
case true: {
let productId = 2;
console.log(productId);
break;
}
}
在切换之前声明变量prodctId。像这样:
const check = true;
let productId;
switch(check) {
case false:
console.log(productId);
break;
case true:
productId = 2;
console.log(productId);
break;
}
提升和临时死区!
let
和 const
被提升到最近的方块,所以它变成这样:
switch (check) {
let productId;
case false:
console.log(productId);
break;
case true:
productId = 2;
console.log(productId);
break;
}
因此由于 temporal dead zone
,出现 ReferenceError