JavaScript一行代码实现If...Else...Else If语句

111

我知道你可以通过这样做: var variable = (condition) ? (true block) : (else block) 用一行if/else语句设置变量,但我想知道是否可以在其中添加else if语句。 感谢大家的建议!


嵌套三元运算符是您所描述的内容。看起来这个回答了这个问题:https://dev59.com/LWkv5IYBdhLWcg3wiRWo - lwalden
9个回答

264

当然,你可以使用嵌套的三元运算符,但它们很难阅读。

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

32
在这种情况下,if() { ... } else if() { ... } else { ... } 可能更易读。 - Spencer Wieczorek
6
三元运算符很难阅读。它们很简洁,缺乏描述性。即使非程序员也知道 if () else () 可能意味着什么。 - Almo
很难阅读...除非您正确使用换行和缩进,否则它可能会非常容易。 - General Grievance

66

简而言之

是的,你可以...... 如果 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时是从右往左结合。简而言之,这意味着最右边的?首先被执行,它在左侧只会取一个最近的操作数,在右侧会取两个操作数,并用:分隔。

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

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)

更好的可读性

上述丑陋的一行代码可以(而且应该)以以下方式进行重写以提高可读性:
(请注意,缩进不会像括号()那样隐式定义正确的闭合。)

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中的"空值合并"。

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.

逻辑运算符
Null合并
短路求值


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
  ..
}

可选链

第四阶段的提案已完成 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)

你的细节太棒了! - t q

17

简单来说:

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

5

if-else:

a = b ? (true block) : (false block)

if-else if-else:

a = b ? (true block) : b = c ? (true block) : (false block)

如果:

a = b && (true block)

if-else-if(嵌套):

a = b ? (true block) : b = c && (true block)
  • 不要想太多,只需实现并查看结果,其中a、b和c是变量

2
简单就是美。 - Paul Iverson Cortez

5

这通常用于变量赋值,它使用二项式条件,例如:

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

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

为了开发的缘故,请不要使用链式结构,因为JavaScript中没有"ElseIf",如果你有多个条件判断的情况,可以使用更快的switch语句。


5

我知道这是一个旧的线程,但是我想发表我的意见。三元运算符可以以以下方式嵌套:

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

例子:

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

3
你可以链接任意多的条件。如果你这样做:
var x = (false)?("1true"):((true)?"2true":"2false");

您将得到 x="2true"
因此,它可以表示为:
var variable = (condition) ? (true block) : ((condition)?(true block):(false block))

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

5
你好,欢迎来到Stack Overflow。为了提供有用的答案,需要进一步扩展这个回复。请解释为什么这是问题的答案。 - Jeroen Heier

0

如果我使用如下代码:

const alpha = a ? a : b ? b : c

这会得到

将嵌套的三元操作提取为独立语句。

因此,我建议使用这个:

const alpha = a || b || c

这对我很有用。


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