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;
}

提升和临时死区!

letconst 被提升到最近的方块,所以它变成这样:

switch (check) {
  let productId;
  case false:
    console.log(productId);
    break;
  case true:
    productId = 2;
    console.log(productId);
    break;
}

因此由于 temporal dead zone,出现 ReferenceError