Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript const和let变量在switch语句中的阴影_Javascript_Node.js_V8 - Fatal编程技术网

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。