Coffeescript 意外的条件评估

Coffeescript Unexpected Conditional Evaluation

.js.coffee:

code = "mw"
console.log code == "mw"                     # true
console.log code == ("ac" || "mw" || "ga")   # false
if code == ("ac" || "mw")
  console.log "inside if"                    # never reached

为什么我不在 if 中创建?

CoffeeScript 的 || 是 JavaScript 的 || 并且来自 fine manual for ||:

expr1 || expr2
Returns expr1 if it can be converted to true; otherwise, returns expr2.

因此 expr1 || expr2 求得整个表达式中的第一个真值(从左到右)。非空字符串是真实的,因此:

("ac" || "mw")

只是一个复杂的说法:

"ac"

还有这个:

if code == ("ac" || "mw")

等同于:

if code == "ac"

并且由于您分配了 code = "mw",所以您说的是:

if "mw" == "ac"

和你的console.log永远不会被执行,因为"mw""ac"不相等。


在您的回答中,您说解决方案是:

if code == "ac" || "mw"

但是 == 的优先级高于 || 所以你实际上是在说:

if (code == "ac") || ("mw")

这将永远是正确的,因为:

  1. 如果code == 'ac'则为真。
  2. 否则表达式的计算结果为 'mw' 并且非空字符串也为真。

如果你想说:

code is either "mw" or "ac"

然后准确地说:

if code == "mw" || code == "ac"

如果您有多个代码要检查,那么您可以使用一个数组来保存您要查找的代码,并且 indexOf (or includes 取决于您关心的 JavaScript 版本):

codes = [ 'mw', 'ac', ... ]
if codes.indexOf(code)
  #...

# or the CoffeeScripty version, `in` is an `indexOf` call in disguise
codes = [ 'mw', 'ac', ... ]
if code in codes
  #...

如果有很多值,并且您认为线性数组搜索太慢,那么您可以使用一个对象来保存这些值(如对您问题的评论):

codes = { mw: true, ac: true, ... }
if codes[code]
  # ...

这是要看的部分

if code == ("ac" || "mw")
  console.log "inside if"

计算结果为 if code == "ac" //this is false so it doesn't print anything