JavaScript 中有四个逻辑运算符:||
(OR)、&&
(AND)、!
(NOT)、??
(空值合并)。这里我们介绍前三个,??
运算符在下一篇文章中介绍。
虽然它们被称为“逻辑”,但它们可以应用于任何类型的变量,而不仅仅是布尔值。它们的结果也可以是任何类型。
让我们看看详情。
|| (OR)
“OR”运算符用两个竖线符号表示
result =
a ||
b;
在经典编程中,逻辑 OR 旨在仅处理布尔值。如果其任何参数为 true
,则返回 true
,否则返回 false
。
在 JavaScript 中,该运算符有点复杂,功能更强大。但首先,让我们看看布尔值会发生什么。
有四种可能的逻辑组合
alert
(
true
||
true
)
;
// true
alert
(
false
||
true
)
;
// true
alert
(
true
||
false
)
;
// true
alert
(
false
||
false
)
;
// false
正如我们所见,结果始终为 true
,除了两个操作数均为 false
的情况。
如果一个操作数不是布尔值,它将在求值时转换为布尔值。
例如,数字 1
被视为 true
,数字 0
被视为 false
if
(
1
||
0
)
{
// works just like if( true || false )
alert
(
'truthy!'
)
;
}
大多数情况下,OR ||
用于 if
语句中,以测试给定条件中的任何条件是否为 true
。
例如
let
hour =
9
;
if
(
hour <
10
||
hour >
18
)
{
alert
(
'The office is closed.'
)
;
}
我们可以传递更多条件
let
hour =
12
;
let
isWeekend =
true
;
if
(
hour <
10
||
hour >
18
||
isWeekend)
{
alert
(
'The office is closed.'
)
;
// it is the weekend
}
OR “||” 查找第一个真值
上面描述的逻辑有点经典。现在,让我们引入 JavaScript 的“额外”功能。
扩展算法的工作方式如下。
给定多个 OR 值
result =
value1 ||
value2 ||
value3;
OR ||
运算符执行以下操作
- 从左到右计算操作数。
- 对于每个操作数,将其转换为布尔值。如果结果为
true
,则停止并返回该操作数的原始值。 - 如果所有操作数都已计算(即全部为
false
),则返回最后一个操作数。
值以其原始形式返回,无需转换。
换句话说,OR ||
链返回第一个真值,如果找不到真值,则返回最后一个真值。
例如
alert
(
1
||
0
)
;
// 1 (1 is truthy)
alert
(
null
||
1
)
;
// 1 (1 is the first truthy value)
alert
(
null
||
0
||
1
)
;
// 1 (the first truthy value)
alert
(
undefined
||
null
||
0
)
;
// 0 (all falsy, returns the last value)
与“纯、经典、仅布尔值的 OR”相比,这导致了一些有趣的用法。
-
从变量或表达式的列表中获取第一个真值。
例如,我们有
firstName
、lastName
和nickName
变量,它们都是可选的(即可以未定义或具有错误值)。让我们使用 OR
||
选择具有数据并显示它的变量(如果没有设置,则显示"Anonymous"
)let
firstName=
""
;
let
lastName=
""
;
let
nickName=
"SuperCoder"
;
alert
(
firstName||
lastName||
nickName||
"Anonymous"
)
;
// SuperCoder
如果所有变量都为假,则会显示
"Anonymous"
。 -
短路求值。
OR
||
运算符的另一个特点是所谓的“短路”求值。这意味着
||
处理其参数,直到达到第一个真值,然后立即返回该值,甚至不触及其他参数。如果操作数不仅仅是一个值,而是一个带有副作用的表达式,例如变量赋值或函数调用,那么此功能的重要性就显而易见了。
在下面的示例中,仅打印第二条消息
true
||
alert
(
"not printed"
)
;
false
||
alert
(
"printed"
)
;
在第一行中,OR
||
运算符在看到true
后立即停止求值,因此不会运行alert
。有时,人们使用此功能仅在左侧条件为假时执行命令。
&& (AND)
AND 运算符用两个和号 &&
表示
result =
a &&
b;
在经典编程中,如果两个操作数都为真,则 AND 返回 true
,否则返回 false
alert
(
true
&&
true
)
;
// true
alert
(
false
&&
true
)
;
// false
alert
(
true
&&
false
)
;
// false
alert
(
false
&&
false
)
;
// false
使用 if
的示例
let
hour =
12
;
let
minute =
30
;
if
(
hour ==
12
&&
minute ==
30
)
{
alert
(
'The time is 12:30'
)
;
}
与 OR 一样,任何值都可以作为 AND 的操作数
if
(
1
&&
0
)
{
// evaluated as true && false
alert
(
"won't work, because the result is falsy"
)
;
}
AND “&&” 找到第一个假值
给定多个 AND 值
result =
value1 &&
value2 &&
value3;
AND &&
运算符执行以下操作
- 从左到右计算操作数。
- 对于每个操作数,将其转换为布尔值。如果结果为
false
,则停止并返回该操作数的原始值。 - 如果已计算所有操作数(即所有操作数都为真),则返回最后一个操作数。
换句话说,AND 返回第一个假值或最后一个值(如果未找到)。
上述规则与 OR 类似。不同之处在于 AND 返回第一个假值,而 OR 返回第一个真值。
示例
// if the first operand is truthy,
// AND returns the second operand:
alert
(
1
&&
0
)
;
// 0
alert
(
1
&&
5
)
;
// 5
// if the first operand is falsy,
// AND returns it. The second operand is ignored
alert
(
null
&&
5
)
;
// null
alert
(
0
&&
"no matter what"
)
;
// 0
我们还可以在一行中传递多个值。看看第一个假值是如何返回的
alert
(
1
&&
2
&&
null
&&
3
)
;
// null
当所有值都为真时,将返回最后一个值
alert
(
1
&&
2
&&
3
)
;
// 3, the last one
&&
的优先级高于 OR ||
AND &&
运算符的优先级高于 OR ||
。
因此,代码 a && b || c && d
本质上与 &&
表达式位于括号中相同:(a && b) || (c && d)
。
||
或 &&
替换 if
有时,人们使用 AND &&
运算符作为“编写 if
的更简短方式”。
例如
let
x =
1
;
(
x >
0
)
&&
alert
(
'Greater than zero!'
)
;
&&
右侧部分的动作仅在求值到达该部分时才会执行。也就是说,仅当 (x > 0)
为 true 时才会执行。
因此,我们基本上有一个类似于
let
x =
1
;
if
(
x >
0
)
alert
(
'Greater than zero!'
)
;
虽然使用 &&
的变体看起来更短,但 if
更明显,并且往往更具可读性。因此,我们建议将每个构造用于其目的:如果我们想要 if
,则使用 if
,如果我们想要 AND,则使用 &&
。
! (NOT)
布尔 NOT 运算符用感叹号 !
表示。
语法非常简单
result =
!
value;
运算符接受单个参数并执行以下操作
- 将操作数转换为布尔类型:
true/false
。 - 返回反向值。
例如
alert
(
!
true
)
;
// false
alert
(
!
0
)
;
// true
有时使用双重 NOT !!
将值转换为布尔类型
alert
(
!
!
"non-empty string"
)
;
// true
alert
(
!
!
null
)
;
// false
也就是说,第一个 NOT 将值转换为布尔并返回反向值,第二个 NOT 再次反转它。最后,我们得到了一个简单的值到布尔的转换。
还有一种更冗长的方式来执行相同操作——内置 Boolean
函数
alert
(
Boolean
(
"non-empty string"
)
)
;
// true
alert
(
Boolean
(
null
)
)
;
// false
NOT !
的优先级是所有逻辑运算符中最高的,因此它总是先于 &&
或 ||
执行。