JavaScript中的开关条件很奇怪

5
我发现以下两个表达方式是等价的,但单个的=并不是一个关系运算符而是一个赋值运算符,为什么它在第二个表达式中起作用呢?
switch (true) 
  {
    case color == 'green':case color == 'red':case color == 'blue':case color == 'pink':
      alert('colorful')
      break;
    case color == 'black':case color == 'white':
      alert('classical')
      break;
    default:
      alert('dull')
      break;              
  }

第二点:

switch (color) 
  {
    case color = 'green':case color = 'red':case color = 'blue':case color = 'pink':
      alert('colorful')
      break;
    case color = 'black':case color = 'white':
      alert('classical')
      break;
    default:
      alert('dull')
      break;              
  }

2
JavaScript在case表达式中应该只使用常量... - Frédéric Hamidi
1
输入“Yellow”,查看 switch 语句后面的颜色是什么 http://jsfiddle.net/x5rG8/. - epascarello
1
@user-12506,那么在Web上处理异步和事件驱动任务时,哪种编程语言更好呢? - bbuecherl
我的评论为什么被删除了? - uSeRnAmEhAhAhAhAhA
@bbuecherl,我从未说过在Web上进行事件驱动和异步任务的语言比JavaScript更好。我只是想指出JS确实有其缺陷。如果他们多加思考,这些缺陷本可以很容易避免。 - uSeRnAmEhAhAhAhAhA
显示剩余2条评论
2个回答

8
在第一个switch语句中,您正在检查布尔值。因此,有效的结果将是true或false。
对于第二个switch语句,我们正在搜索颜色。赋值的结果是赋值值本身。
color = 'green'将返回绿色,并且与编写case 'green':完全相同,只不过它还会更改color的值。 但是,这是一个大问题,您正在在检查颜色时更改color的值,这可能会导致重大副作用。
最好使用正确的正式样式case 'green':而不是其他变体。特别不是赋值变体。

2
颜色的值似乎并不总是会改变:var color='red'; switch(color) { case color='green':case color='red':case color='pink': break; }; console.log(color);//'red' 如果将初始化改为 'blue',则可以预期得到 'pink'。非常有趣。 - Tibos
1
color='red' 时,在执行完 case color='red' 后,它不会查找其他情况,因此它将保持定义为 red。而在查找 blue 时,它将搜索所有情况(并执行 color='' 的内容),因此它将被更改为最后一个情况,即你的例子中的 pink - bbuecherl
@Tibos,确实有趣,不同的编程语言当然会以不同的方式执行它。 - Orel Eraki

0

我不确定 switch 在 CPU 内部是如何工作的,但我猜测当进入 switch 语句时,color 的值会被临时存储。然后,分配的结果(等于所分配的值)将与存储的 switch 值进行比较,而不是与变量本身进行比较。我认为这是因为你也可以这样做:

var color = 'whit'
switch(color + 'e')
// value "white" stored for comparison...
{
  case color = 'green':
  case color = 'red':
  case color = 'blue':
  case color = 'pink':
    alert('colorful')
    break;
  case color = 'black':
  // (color = 'white') == 'white'
  // 'white' is compared to the stored value
  case color = 'white':
    alert('classical')
    break;
  default:
    alert('dull')
    break;              
}

更新: 在下面的例子中,value 只被检索一次(在 switch 语句的开头),但被多次设置(在每个 case 语句中)。因此:只有变量的 (而不是变量本身)用于比较。

function Field(val){
    this.__defineGetter__("value", function(){
        var val = parseInt(Math.random() * 10);
        console.log('get: ' + val);
        return val;
    });
    this.__defineSetter__("value", function(val){
        console.log('set: ' + val);
    });
}

var field = new Field();
switch (field.value) {
    case field.value = 0:
        break
    case field.value = 1:
        break
    case field.value = 2:
        break
    case field.value = 3:
        break
    case field.value = 4:
        break
    case field.value = 5:
        break
    case field.value = 6:
        break
    case field.value = 7:
        break
    case field.value = 8:
        break
    case field.value = 9:
        break
    default:
        break
}

// output (e.g.)
// get: 5
// set: 1
// set: 2
// set: 3
// set: 4
// set: 5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接