切换案例的Javascript范围变量?

时间:2016-12-06 15:30:29

标签: javascript scope switch-statement

在C中,您可以将变量范围限定为切换案例,例如this

使用javascript我会使用以下内容获得意外令牌:

const i = 1

switch (i) {
    // variables scoped to switch
    var s
    var x = 2342
    case 0:
      s = 1 + x
      break
    case 1:
      s = 'b'
      break
}

还有其他方法可以做到这一点,还是应该在交换机外声明我的变量?

编辑:

这是我考虑过的一种解决方法,但它并没有最终起作用。原因是每个案例都有自己的范围。

const i = 1

switch (i) {
    case i:
      // variables scoped to switch
      var s
      var x = 2342
    case 0:
      s = 1 + x
      break
    case 1:
      s = 'b'
      break
}

5 个答案:

答案 0 :(得分:31)

一些替代方案:

/* curly braces inside the case */

const i = 1

switch (i) {
  case 0: {
    let x = 2342;
    let s = 1 + x;
    console.log(x+' & '+s+' from inside');
  } break;
  case 1: {
    let x = 2342;
    let s = 'b';
    console.log(x+' & '+s+' from inside'); /* 2342 & b from inside */
  } break;
}

console.log(x+' & '+s+' from outside'); /* Uncaught ReferenceError */

/* curly braces outside the switch */

const i = 1

{
  let x = 2342;
  let s;
  switch (i) {
    case 0:
      s = 1 + x;
      break;
    case 1:
      s = 'b';
      break;
  }
  console.log(x+' & '+s+' from inside'); /* 2342 & b from inside */
}

console.log(x+' & '+s+' from outside'); /* Uncaught ReferenceError */

答案 1 :(得分:4)

由于var无论如何都会在 function 范围内创建变量,因此使用它是毫无意义的。为了在功能范围之下的粒度下工作,你必须使用let和支持它的浏览器/编译器,然后引入一个你可以范围内的新块(在switch内,它只是无效的语法):

if (true) {
    let s;

    switch (i) {
        ...
    }
}

此范围s范围为if块,所有意图和目的都与此处的“switch范围”相同。

如果您不支持let,则需要使用IIFE:

(function () {
    var s;

    switch (...) ...
})();

答案 2 :(得分:2)

不,这是无效的语法。预计casedefault语句在switch内。您可以在此处查看规范:http://www.ecma-international.org/ecma-262/5.1/#sec-12.11

您也可以尝试在JSLinter中输入代码并发现这是一个错误:http://jslint.com/

Expected 'case' and instead saw 'var'.

您正在考虑的解决方法与将它们放在switch语句之外是一回事。请记住,var具有功能级别范围,不是块级范围。这意味着它们绑定到包含开关的整个函数。您应该在交换机之外声明它们,因为这是可以访问的地方。

const i = 1;
var s;
var x = 2342;

switch (i) {
  case 0:
    s = 1 + x;
    break;
  case 1:
    s = 'b';
    break;
  default:
    break;
}

console.log("s is " + s);

答案 3 :(得分:0)

应在交换机外声明。以下可能会有所帮助:

var i = 1, x = 2342;
var s;
switch (i)
 {        
    case 0:
      s = 1 + x;
      break;
    case 1:
      s = 'b';
      break;
}
console.log("s is " + s);

答案 4 :(得分:-1)

JavaScript定义了3个范围:

  • 全球 - 功能中没有任何内容
  • 功能 - 使用var关键字在函数中声明的任何内容
  • 阻止 - 使用{}
  • 在块容器(let)中声明的任何内容

因此,要创建整个构造的范围,您有两个选择:功能或阻止

  

为了通过函数获取您正在寻找的行为:

const i = 1

function doSwitch(data){

  // variables are not scoped to switch, but are 
  // scoped to the function, which only contains 
  // the switch.
  var s;
  var x = 2342;
  
  switch (data) {
    case 0:
      s = 1 + x;
      break;
    case 1:
      s = 'b';
      break;
    default:
      s = "other";
  }

  console.log("s is " + s)

}

doSwitch(18);

  

或者,为了使用let

获取块的功能

const i = 1;

// Wrapping the switch in its own block allows for let to work:
{
      // variables are not scoped to switch, but are 
      // scoped to the function, which only contains 
      // the switch.
      let s;
      let x = 2342;
      
      switch (i) {
        case 0:
          s = 1 + x;
          break;
        case 1:
          s = 'b';
          break;
        default:
          s = "other";
      }

      console.log("s is " + s)
}

// Test:
console.log(s, x);  // ReferenceError