JavaScript一行If ... else ... else if语句


72

我知道您可以通过执行用一行if / else语句设置变量var variable = (condition) ? (true block) : (else block),但是我想知道是否有一种方法可以在其中放置else if语句。任何建议将不胜感激,谢谢大家!


嵌套三元运算符就是您要描述的。看起来像这样回答了问题:stackoverflow.com/questions/10526739/…–
lwalden

Answers:


182

当然,您可以执行嵌套的三元运算符,但它们很难阅读。

var variable = (condition) ? (true block) : ((condition2) ? (true block2) : (else block2))

17
是的,在这种情况下if() { ... } else if() { ... } else { ... }可能更具可读性。
Spencer Wieczorek

3
任何三元运算符都很难阅读。它们简洁而不是描述性的。甚至非程序员都知道if()else()可能意味着什么。
Almo

49

tl; dr

是的,您可以... 如果a则a,否则b则c则c(b),否则b,否则为null

a ? a : (b ? (c ? c(b) : b) : null)

a
  ? a
  : b
      ? c
        ? c(b)
        : b
      : null

更长的版本

?:用作内联if-else的三元运算符是正确的关联。总之,这意味着最右边?被首先输送,它恰恰是一个在左边和最亲密的操作数2,用:,在右边。

实际上,请考虑以下语句(与上面相同)

a ? a : b ? c ? c(b) : b : null

最右边的东西?首先被送入,因此找到它及其周围的三个参数,并依次向左扩展到另一个?

   a ? a : b ? c ? c(b) : b : null
                 ^                  <---- RTL
1.            |1-?-2----:-3|
             ^ <-
2.        |1-?|--2---------|:-3---|
     ^ <-
3.|1-?-2-:|--3--------------------|

result: a ? a : (b ? (c ? c(b) : b) : null)

这是计算机的读取方式:

  1. 术语a已读。
    节点:a
  2. ?读非终结符。
    节点:a ?
  3. 术语a已读。
    节点:a ? a
  4. :读非终结符。
    节点:a ? a :
  5. 术语b已读。
    节点:a ? a : b
  6. ?读取非终结符,触发右关联规则。关联性决定:
    节点:a ? a : (b ?
  7. 术语c已读。
    节点:a ? a : (b ? c
  8. ?读取非终结符,重新应用右关联规则。
    节点:a ? a : (b ? (c ?
  9. 术语c(b)已读。
    节点:a ? a : (b ? (c ? c(b)
  10. :读非终结符。
    节点:a ? a : (b ? (c ? c(b) :
  11. 术语b已读。
    节点:a ? a : (b ? (c ? c(b) : b
  12. :读非终结符。?:满足先前作用域的三元运算符,并且作用域已关闭。
    节点:a ? a : (b ? (c ? c(b) : b) :
  13. 术语null已读。
    节点:a ? a : (b ? (c ? c(b) : b) : null
  14. 没有令牌可供读取。关闭剩余的左括号。
    #结果是:a ? a : (b ? (c ? c(b) : b) : null)

更好的可读性

从上面的丑陋oneliner可以(也应该)被改写为可读性:
(注意,缩进并没有隐含地定义正确的关闭装置,如括号()做的。)

a
  ? a
  : b
      ? c
        ? c(b)
        : b
      : null

例如

return a + some_lengthy_variable_name > another_variable
        ? "yep"
        : "nop"

更多阅读

Mozilla:JavaScript条件运算符
Wiki:运算符关联


奖励:逻辑运算符

var a = 0 // 1
var b = 20
var c = null // x=> {console.log('b is', x); return true} // return true here!

a
  && a
  || b
      && c
        && c(b) // if this returns false, || b is processed
        || b
      || null

在这个例子中使用逻辑运算符是很丑陋和错误的,但这就是它们的亮点...

“空合并”

如下面的链接所述,此方法具有一些细微的限制。有关正确的解决方案,请参阅Bonus2中的Nullish合并。

function f(mayBeNullOrFalsy) {
  var cantBeNull = mayBeNullOrFalsy || 42                    // "default" value
  var alsoCantBe = mayBeNullOrFalsy ? mayBeNullOrFalsy : 42  // ugly...
  ..
}

短路评估

false && (anything) // is short-circuit evaluated to false.
true || (anything)  // is short-circuit evaluated to true.

逻辑运算符
空合并
短路评估


Bonus2:JS新功能

正确的“空位合并”

developer.mozilla.org〜Nullish_coalescing_operator

function f(mayBeNullOrUndefined, another) {
  var cantBeNullOrUndefined = mayBeNullOrUndefined ?? 42
  another ??= 37 // nullish coalescing self-assignment
  another = another ?? 37 // same effect
  ..
}

可选链接

第4阶段完成的提案https://github.com/tc39/proposal-optional-chaining https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

// before
var street = user.address && user.address.street
// after
var street = user.address?.street

// combined with Nullish coalescing
// before
var street = user.address
  ? user.address.street
  : "N/A"

// after
var street = user.address?.street ?? "N/A"

// arrays
obj.someArray?.[index]

// functions
obj.someMethod?.(args)

9

简单来说:

var x = (day == "yes") ? "Good Day!" : (day == "no") ? "Good Night!" : "";

1
不,您的语法不正确,您在:嵌套的三元语句中缺少。在浏览器中测试...
fyllepo '19

@Masood_Aslami感谢您的纠正。我已经投票了。
fyllepo '19

@fyllepo谢谢
Masood

5

这主要用于分配变量,并使用二项式条件,例如。

var time = Date().getHours(); // or something

var clockTime = time > 12 ? 'PM' : 'AM' ;

如果为了开发而不使用链接,则没有ElseIf。switch如果您在.js中有多个条件,则可以使用它来更快


4

我知道这是一个旧线程,但是以为我会花两美分。三元运算符可以按以下方式嵌套:

var variable = conditionA ? valueA : (conditionB ? valueB: (conditionC ? valueC : valueD));

例:

var answer = value === 'foo' ? 1 :
    (value === 'bar' ? 2 : 
        (value === 'foobar' ? 3 : 0));

2

您可以根据需要链接尽可能多的条件。如果您这样做:

var x = (false)?("1true"):((true)?"2true":"2false");

你会得到 x="2true"

因此可以表示为:

var variable = (condition) ? (true block) : ((condition)?(true block):(false block))

2
  a === "a" ? do something
: a === "b" ? do something
: do something

4
嗨,欢迎堆栈溢出。为了获得有用的答案,需要扩展此反应。解释为什么这是问题的答案。
Jeroen Heier
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.