const已在ES6开关块中声明

Ran*_*lva 11 javascript const node.js ecmascript-6

考虑一下该文件 sample.es6

switch (1) {
    case 1:
        const foo = 1;
        break;
    case 2:
        const foo = 2;
        break;
}
Run Code Online (Sandbox Code Playgroud)

如果我用Node运行它我得到了

$ node --version
v4.2.11
$ node sample.es6 
/tmp/sample.es6:6
const foo = 2;
^

SyntaxError: Identifier 'foo' has already been declared
    at Object.<anonymous> (/tmp/sample.es6:1:11)
    at Module._compile (module.js:435:26)
    at Object.Module._extensions..js (module.js:442:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Function.Module.runMain (module.js:467:10)
    at startup (node.js:134:18)
    at node.js:961:3
Run Code Online (Sandbox Code Playgroud)

为什么我收到此错误?节点不应该评估const foo = 2;.

Igo*_*ush 14

你得到的是SyntaxError因为你在同一范围内重新声明一个变量; 一个switch语句只包含一个底层块,而不是每个块一个块case.

JavaScript在编译时抛出错误."节点不应该评估const foo = 2;"是无关紧要的,因为在Node评估任何内容之前会发生此错误.

const(以及许多新的ES6功能,例如新的模块规范)的一个目的是使编译器能够进行一些静态分析.const告诉编译器永远不会重新分配变量,这允许引擎更有效地处理它.

当然,这需要进行编译时检查以确保变量确实从未被重新分配(或重新声明),这就是您看到错误的原因.

  • 也许值得一提的是switch语句中只有一个底层块.有人可能会猜测每个案例都有一个块范围,但事实并非如此.https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/let#Temporal_dead_zone_and_errors_with_let (3认同)
  • 这是"常量"的一点.另一个是防止我破坏我自己的变量. (2认同)

Hin*_*ich 12

您可以围绕案例创建范围块,而eslint会很高兴:

switch (1) {
    case 1: {
        // notice these extra curly braces
        const foo = 1;
        break;
    }
    case 2: {
        const foo = 2;
        break;
    {
}
Run Code Online (Sandbox Code Playgroud)


Fat*_*lla 7

您可以使用立即调用函数表达式(IIFE)进行const分配:

const foo=(function(){
  switch (1) {
    case 1:
      return 1;
      break;
    case 2:
      return 2;
      break;
  }
})();

console.log('foo = '+foo); /* foo = 1 */
Run Code Online (Sandbox Code Playgroud)

可选地,您可以在大括号内的情况下创建一个范围,但是您不能在switch块外部访问foo:

switch (1) {
  case 1: {
    const foo = 1;
    console.log(foo+' from inside'); /* 1 from inside */
  } break;
  case 2: {
    const foo = 2;
    console.log(foo+' from inside');
  } break;
}

console.log(foo+' from outside'); /* foo is not defined */
Run Code Online (Sandbox Code Playgroud)


bgo*_*rdt 0

使用临时变量来确定值,然后在确定值后设置常量。

let bar;
switch (1) {
    case 1:
        bar = 1;
        break;
    case 2:
        bar = 2;
        break;
}
const foo = bar;
Run Code Online (Sandbox Code Playgroud)