? :
)x && y
),或 (x || y
)x && y
)||
)!
)基本类型*布尔值*包含两个值 - false
和 true
> typeof false'boolean'
> typeof true'boolean'
“转换为 [类型]” 的含义
“转换为 [类型]” 是 “将任意值转换为 [类型] 类型的值” 的简称。
您可以通过以下三种方式将任意值 x
转换为布尔值。
Boolean(x)
最具描述性;推荐。
x ? true : false
使用条件运算符(本章稍后解释)。
!!x
使用逻辑非运算符 (!
)。此运算符将其操作数强制转换为布尔值。它被应用两次以获得非否定结果。
表 4 描述了如何将各种值转换为布尔值。
x |
Boolean(x) |
---|---|
undefined |
false |
null |
false |
boolean | x (无变化) |
number | 0 → false , NaN → false |
其他数字 → true |
|
bigint | 0 → false |
其他数字 → true |
|
string | '' → false |
其他字符串 → true |
|
symbol | true |
object | 始终为 true |
在检查 if
语句、while
循环或 do-while
循环的条件时,JavaScript 的工作方式可能与您预期的不同。以以下条件为例
if (value) {}
在许多编程语言中,此条件等效于
if (value === true) {}
但是,在 JavaScript 中,它等效于
if (Boolean(value) === true) {}
也就是说,JavaScript 会检查 value
转换为布尔值时是否为 true
。这种检查非常普遍,因此引入了以下名称
true
,则称其为*真值*。false
,则称其为*假值*。每个值要么是真值,要么是假值。查阅表 4,我们可以列出所有假值
undefined
null
false
0
、NaN
0n
''
所有其他值(包括所有对象)都是真值
> Boolean('abc')true
> Boolean([])true
> Boolean({})true
if (x) {
// x is truthy
}
if (!x) {
// x is falsy
}
if (x) {
// x is truthy
else {
} // x is falsy
}
const result = x ? 'truthy' : 'falsy';
最后一行中使用的条件运算符将在本章稍后解释。
练习:真值
exercises/booleans/truthiness_exrc.mjs
在 JavaScript 中,如果您读取不存在的内容(例如,缺少的参数或缺少的属性),您通常会得到 undefined
作为结果。在这些情况下,存性检查相当于将值与 undefined
进行比较。例如,以下代码检查对象 obj
是否具有属性 .prop
if (obj.prop !== undefined) {
// obj has property .prop
}
由于 undefined
是假值,我们可以将此检查缩短为
if (obj.prop) {
// obj has property .prop
}
基于真值的存性检查有一个陷阱:它们不是很精确。考虑前面的例子
if (obj.prop) {
// obj has property .prop
}
如果满足以下条件,则跳过 if
语句的主体
obj.prop
(在这种情况下,JavaScript 返回 undefined
)。但是,如果满足以下条件,也会跳过它
obj.prop
为 undefined
。obj.prop
是任何其他假值(null
、0
、''
等)。在实践中,这很少会导致问题,但您必须意识到这个陷阱。
真值检查通常用于确定函数的调用者是否提供了参数
function func(x) {
if (!x) {
throw new Error('Missing parameter x');
}// ···
}
从好的方面来说,这种模式是既定的,而且很短。它会针对 undefined
和 null
正确地抛出错误。
从不好的方面来说,存在前面提到的陷阱:该代码还会针对所有其他假值抛出错误。
另一种方法是检查 undefined
if (x === undefined) {
throw new Error('Missing parameter x');
}
真值检查也经常用于确定属性是否存在
function readFile(fileDesc) {
if (!fileDesc.path) {
throw new Error('Missing property: .path');
}// ···
}readFile({ path: 'foo.txt' }); // no error
这种模式也是既定的,并且具有通常的注意事项:它不仅在属性缺失时抛出,而且在属性存在且具有任何假值时也会抛出。
如果您真的想检查属性是否存在,则必须使用in
运算符
if (! ('path' in fileDesc)) {
throw new Error('Missing property: .path');
}
? :
)条件运算符是 if
语句的表达式版本。其语法为
«condition» ? «thenExpression» : «elseExpression»
它的计算方式如下
condition
为真值,则计算并返回 thenExpression
。elseExpression
。条件运算符也称为*三元运算符*,因为它有三个操作数。
示例
> true ? 'yes' : 'no''yes'
> false ? 'yes' : 'no''no'
> '' ? 'yes' : 'no''no'
以下代码演示了无论通过条件选择“then”和“else”中的哪一个分支,都只计算该分支。另一个分支不计算。
const x = (true ? console.log('then') : console.log('else'));
// Output:
// 'then'
x && y
),或 (x || y
)二元逻辑运算符 &&
和 ||
是*值保留*和*短路求值*的。
*值保留*意味着操作数被解释为布尔值,但返回时保持不变
> 12 || 'hello'12
> 0 || 'hello''hello'
*短路求值*意味着如果第一个操作数已经确定了结果,则不计算第二个操作数。唯一另一个延迟计算其操作数的运算符是条件运算符。通常,在执行操作之前会计算所有操作数。
例如,如果第一个操作数为假值,则逻辑与 (&&
) 不会计算其第二个操作数
const x = false && console.log('hello');
// No output
如果第一个操作数为真值,则执行 console.log()
const x = true && console.log('hello');
// Output:
// 'hello'
x && y
)表达式 a && b
(“a
与 b
”)的计算方式如下
a
。b
并返回结果。换句话说,以下两个表达式大致等效
&& b
a !a ? a : b
示例
> false && truefalse
> false && 'abc'false
> true && falsefalse
> true && 'abc''abc'
> '' && 'abc'''
||
)表达式 a || b
(“a
或 b
”)的计算方式如下
a
。b
并返回结果。换句话说,以下两个表达式大致等效
|| b
a ? a : b a
示例
> true || falsetrue
> true || 'abc'true
> false || truetrue
> false || 'abc''abc'
> 'abc' || 'def''abc'
||
) 的传统用例:提供默认值ECMAScript 2020 引入了空值合并运算符 (??
) 来提供默认值。在此之前,逻辑或用于此目的
const valueToUse = receivedValue || defaultValue;
有关 ??
以及在这种情况下 ||
的缺点的更多信息,请参阅§14.4 “空值合并运算符 (??
) 用于默认值 [ES2020]”。
传统练习:通过或运算符 (||
) 提供默认值
exercises/booleans/default_via_or_exrc.mjs
!
)表达式 !x
(“非 x
”)的计算方式如下
x
。false
。true
。示例
> !falsetrue
> !truefalse
> !0true
> !123false
> !''true
> !'abc'false
测验
请参阅测验应用程序。