tl;博士
是的,你可以... 如果 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)
这是计算机读取它的方式:
- 已读取术语
a。
节点:a
- 已读取非终结符
?。
节点:a ?
- 已读取术语
a。
节点:a ? a
- 已读取非终结符
:。
节点:a ? a :
- 已读取术语
b。
节点:a ? a : b
- 读取非终结符
?,触发右关联规则。关联性决定:
节点:a ? a : (b ?
- 术语
c 已读取。
节点:a ? a : (b ? c
- 读取非终结符
?,重新应用右关联规则。
节点:a ? a : (b ? (c ?
- 已读取术语
c(b)。
节点:a ? a : (b ? (c ? c(b)
- 已读取非终结符
:。
节点:a ? a : (b ? (c ? c(b) :
- 已读取术语
b。
节点:a ? a : (b ? (c ? c(b) : b
- 非终结符
: 被读取。满足先前作用域的三元运算符?: 并关闭作用域。
节点:a ? a : (b ? (c ? c(b) : b) :
- 已读取术语
null。
节点:a ? a : (b ? (c ? c(b) : b) : null
- 没有要读取的令牌。关闭剩余的左括号。
#结果是: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 Conditional Operator
Wiki: Operator Associativity
奖励:逻辑运算符
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 coalescing。
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.
Logical operators
Null coalescence
Short-circuit evaluation
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)