Javascript const和let变量在switch语句中的阴影
我有以下代码。唯一有趣的是,我在第二个开关案例中重新声明了Javascript const和let变量在switch语句中的阴影,javascript,node.js,v8,Javascript,Node.js,V8,我有以下代码。唯一有趣的是,我在第二个开关案例中重新声明了productId 让productId=1; 常量检查=真; 开关(检查){ 案例错误: console.log(productId); 打破 大小写正确: 设productId=2; console.log(productId); 打破 }出现错误是因为您定义了变量productId两次(在switch语句之前,在第二种情况下) 让productId=1; 常量检查=真; 开关(检查){ 案例错误: console.log(pro
productId
让productId=1;
常量检查=真;
开关(检查){
案例错误:
console.log(productId);
打破
大小写正确:
设productId=2;
console.log(productId);
打破
}
出现错误是因为您定义了变量productId
两次(在switch语句之前,在第二种情况下)
让productId=1;
常量检查=真;
开关(检查){
案例错误:
console.log(productId);
打破
大小写正确:
productId=2;//在开关
块中有一个let
声明。这种声明有点“半挂起”。它们不像var
,但是开关
块中的productId
符号基本上由第二个案例
中的声明声明声明声明。因此,外部productId
被隐藏
如果将第二种情况的代码包装在{}
中,则可以正常工作
switch (check) {
case false:
console.log(productId);
break;
case true: {
let productId = 2;
console.log(productId);
break;
}
}
在开关之前声明变量prodcId。如下所示:
const check = true;
let productId;
switch(check) {
case false:
console.log(productId);
break;
case true:
productId = 2;
console.log(productId);
break;
}
吊装和临时死区!
让
和const
被提升到最近的区块,这样它就会变成这样:
switch (check) {
let productId;
case false:
console.log(productId);
break;
case true:
productId = 2;
console.log(productId);
break;
}
因此,由于时间死区
,当您将check更改为false temporal dead zone@CodeManiac yea时,会出现ReferenceError@Pointy。感谢您的工作,我现在就知道了,但它在语义上与问题中的代码不同。实际上,这将覆盖初始的productId
值。而第二个变量的作用域则不会。如果这不是故意的,我建议使用不同的变量名,因为这会导致混淆(许多linter不允许这样做)。谢谢您的回答。我知道它是“半悬挂式”的,但必须有一些规则来解释为什么或如何发生这种情况。@asamolion它被描述为暂时死区
。下面的评论链接question@asamolion当然有规则。开关
块中的let
声明({}
对于整个开关
)将productId
标识为块的局部变量。但是,由于它发生在第二个案例
中,因此第一个案例
中的代码无法“查看”但是,因为它在后面。这里有一行需要注意的重要内容您可能会在switch语句中遇到错误,因为只有一个块。
这确实有效,但其含义与问题中的代码不同。(好吧,如果做得好会怎么样。)@你能解释一下你的担忧吗?我不明白你的意思。问题中的代码在开关
语句的范围内创建了一个新变量。对该变量的更改不会更改外部productId
。现在,我不知道OP真正想要做什么,因此你的更改可能完全正确。如果让我们
像您演示的那样被提升,那么它不应该抛出错误,事实上它应该打印未定义的“所有声明(函数、变量、let、常量和类)都是用JavaScript提升的,而var声明是用未定义的进行初始化的,但let和const声明保持未初始化状态。”来源:let
未初始化的情况是,在定义变量之前尝试访问变量console.log(x);let x;
使用var
似乎可以,highting
被定义为在内存中创建变量,所以是highed。