企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
## 14.布尔值 > 原文: [http://exploringjs.com/impatient-js/ch_booleans.html](http://exploringjs.com/impatient-js/ch_booleans.html) > > 贡献者:[飞龙](https://github.com/wizardforcel) 基本类型*布尔值*包含两个值 - `false`和`true`: ```js > typeof false 'boolean' > typeof true 'boolean' ``` ### 14.1。转换为布尔值 这三种方法可以将任意值`x`转换为布尔值。 * `Boolean(x)` 最具描述性;推荐。 * `x ? true : false` 使用条件运算符([在本章后面解释](ch_booleans.html#conditional-operator))。 * `!!x` 使用[逻辑非运算符(`!`)](ch_booleans.html#logical-not)。此运算符将其操作数强制转换为布尔值。它被第二次应用来获得非否定的结果。 表 4 描述了各种值如何转换为布尔值。 表 4:将值转换为布尔值 | `x` | `Boolean(x)` | | --- | --- | | `undefined` | `false` | | `null` | `false` | | 布尔值 | `x`(无变化) | | 数值 | `0 → false`,`NaN → false` | | | 其他数字` → true` | | 字符串值 | `'' → false` | | | 其他字符串` → true` | | 对象值 | 总是`true` | ### 14.2。真值和假值 在 JavaScript 中,如果您读取了不存在的内容(例如缺失参数或缺失属性),则通常会得到`undefined`。在这些情况下,存在性检查相当于将值与`undefined`进行比较。例如,以下代码检查对象`obj`是否具有属性`.prop`: ```js if (obj.prop !== undefined) { // obj has property .prop } ``` 为简化此检查,我们可以使用一个事实,`if`语句始终将其条件值转换为布尔值: ```js if ('abc') { // true, if converted to boolean console.log('Yes!'); } ``` 因此,我们可以使用以下代码来检查`obj.prop`是否存在。这与`undefined`相比不太精确,但也更短: ```js if (obj.prop) { // obj has property .prop } ``` 这种简化的检查非常流行,引入了以下两个名称: * 如果它在转换为布尔值时是`true`,则称为*真值*。 * 如果它在转换为布尔值时是`false`,则称为*假值*。 查询表 4,我们可以列出一个详尽的假值列表: * `undefined`,`null` * 布尔:`false` * 数字:`0`,`NaN` * 字符串:`''` 所有其他值(包括*所有*对象)都是真值: ```js > Boolean('abc') true > Boolean([]) true > Boolean({}) true ``` #### 14.2.1。陷阱:真实性检查是不精确的 真实性检查有一个陷阱:它们不是很精确。考虑前面的例子: ```js if (obj.prop) { // obj has property .prop } ``` 如果出现以下情况,则跳过`if`语句的正文: * 缺少`obj.prop`(在这种情况下,JavaScript 返回`undefined`)。 但是,如果出现以下情况,也会跳过它: * `obj.prop`是`undefined`。 * `obj.prop`是任何其他假值(`null`,`0`,`''`等)。 在实践中,这很少会引起问题,但你必须意识到这个陷阱。 #### 14.2.2。检查真实性或虚假性 ```js if (x) { // x is truthy } if (!x) { // x is falsy } if (x) { // x is truthy } else { // x is falsy } const result = x ? 'truthy' : 'falsy'; ``` 最后一行中使用的条件运算符将在[本章后面的章节](ch_booleans.html#conditional-operator)中解释。 #### 14.2.3。用例:是否提供了参数? 真值检查通常用于确定函数的调用者是否提供了参数: ```js function func(x) { if (!x) { throw new Error('Missing parameter x'); } // ··· } ``` 从好的方面来说,这种模式已经建立并且很短。它正确地为`undefined`和`null`抛出错误。 而另一面,有前面提到的陷阱:代码也会对所有其他假值抛出错误。 另一种方法是检查`undefined`: ```js if (x === undefined) { throw new Error('Missing parameter x'); } ``` #### 14.2.4。用例:存在属性吗? 真实性检查通常也用于确定属性是否存在: ```js function readFile(fileDesc) { if (!fileDesc.path) { throw new Error('Missing property: .path'); } // ··· } readFile({ path: 'foo.txt' }); // no error ``` 这种模式也已建立,并且有一个常见的警告:它不仅会在属性丢失时抛出,而且如果它存在并且具有任何假值。 如果你真的想检查属性是否存在,你必须使用[`in`运算符](ch_single-objects.html#in-operator): ```js if (! ('path' in fileDesc)) { throw new Error('Missing property: .path'); } ``` ![](https://img.kancloud.cn/3e/d5/3ed5755d562179ae6c199264f5e21157.svg) **练习:真实性** `exercises/booleans/truthiness_exrc.js` ### 14.3。条件运算符(`? :`) 条件运算符是`if`语句的表达式版本。它的语法是: ```js «condition» ? «thenExpression» : «elseExpression» ``` 求值如下: * 如果`condition`是真值,求值并返回`thenExpression`。 * 否则,求值并返回`elseExpression`。 条件运算符也称为*三元运算符*,因为它有三个操作数。 例子: ```js > true ? 'yes' : 'no' 'yes' > false ? 'yes' : 'no' 'no' > '' ? 'yes' : 'no' 'no' ``` 下面的代码演示了,通过条件选择`then`和`else`两个分支中的任何一个 - 只求值该分支。另一个分支不是。 ```js const x = (true ? console.log('then') : console.log('else')); // Output: // 'then' ``` ### 14.4。二元逻辑运算符:和(`x && y`),或(`x || y`) 运算符`&&`和`||`是*值保留*和*短路*的。那是什么意思? *值保留*意味着操作数被解释为布尔值,但返回值不变: ```js > 12 || 'hello' 12 > 0 || 'hello' 'hello' ``` *短路*表示:如果第一个操作数已经确定了结果,则不求值第二个操作数。延迟求值其操作数的唯一其他运算符是条件运算符:通常,在执行操作之前求值所有操作数。 例如,如果第一个操作数是假值,则逻辑和(`&&`)不会计算其第二个操作数: ```js const x = false && console.log('hello'); // No output ``` 如果第一个操作数是真值,则执行`console.log()`: ```js const x = true && console.log('hello'); // Output: // 'hello' ``` #### 14.4.1。逻辑和(`x && y`) 表达式`a && b`(“`a`和`b`”)的求值如下: * 求值`a`。 * 结果是假值吗?把它返回。 * 否则,求值`b`并返回结果。 换句话说,以下两个表达式大致相同: ```js a && b !a ? a : b ``` 例子: ```js > false && true false > false && 'abc' false > true && false false > true && 'abc' 'abc' > '' && 'abc' '' ``` #### 14.4.2。逻辑或(`||`) 表达式`a || b`(“`a`或`b`”)的求值如下: * 求值`a`。 * 结果是真值?把它返回。 * 否则,求值`b`并返回结果。 换句话说,以下两个表达式大致相同: ```js a || b a ? a : b ``` 例子: ```js > true || false true > true || 'abc' true > false || true true > false || 'abc' 'abc' > 'abc' || 'def' 'abc' ``` #### 14.4.3。通过逻辑或(`||`)的默认值 有时您会收到一个值,如果它不是`null`或`undefined`,则只想使用它。否则,您希望使用默认值作为后备。您可以通过`||`运算符执行此操作: ```js const valueToUse = valueReceived || defaultValue; ``` 以下代码显示了一个真实示例: ```js function countMatches(regex, str) { const matchResult = str.match(regex); // null or Array return (matchResult || []).length; } ``` 如果`str`内有`regex`的一个或多个匹配项,则`.match()`返回一个数组。如果没有匹配,则很遗憾地返回`null`(而不是空数组)。我们通过`||`运算符来解决这个问题。 ![](https://img.kancloud.cn/3e/d5/3ed5755d562179ae6c199264f5e21157.svg) **练习:通过或运算符(`||`)**的默认值 `exercises/booleans/default_via_or_exrc.js` ### 14.5。逻辑非(`!`) 表达式`!x`(“Not `x`”)的求值如下: * 求值`x`。 * 这是真值?返回`false`。 * 否则,返回`true`。 例子: ```js > !false true > !true false > !0 true > !123 false > !'' true > !'abc' false ``` ![](https://img.kancloud.cn/ff/a8/ffa8e16628cad59b09c786b836722faa.svg) **测验** 参见[测验应用程序](ch_quizzes-exercises.html#quizzes)。