## 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');
}
```
 **練習:真實性**
`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`(而不是空數組)。我們通過`||`運算符來解決這個問題。
 **練習:通過或運算符(`||`)**的默認值
`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
```
 **測驗**
參見[測驗應用程序](ch_quizzes-exercises.html#quizzes)。
- I.背景
- 1.關于本書(ES2019 版)
- 2.常見問題:本書
- 3. JavaScript 的歷史和演變
- 4.常見問題:JavaScript
- II.第一步
- 5.概覽
- 6.語法
- 7.在控制臺上打印信息(console.*)
- 8.斷言 API
- 9.測驗和練習入門
- III.變量和值
- 10.變量和賦值
- 11.值
- 12.運算符
- IV.原始值
- 13.非值undefined和null
- 14.布爾值
- 15.數字
- 16. Math
- 17. Unicode - 簡要介紹(高級)
- 18.字符串
- 19.使用模板字面值和標記模板
- 20.符號
- V.控制流和數據流
- 21.控制流語句
- 22.異常處理
- 23.可調用值
- VI.模塊化
- 24.模塊
- 25.單個對象
- 26.原型鏈和類
- 七.集合
- 27.同步迭代
- 28.數組(Array)
- 29.類型化數組:處理二進制數據(高級)
- 30.映射(Map)
- 31. WeakMaps(WeakMap)
- 32.集(Set)
- 33. WeakSets(WeakSet)
- 34.解構
- 35.同步生成器(高級)
- 八.異步
- 36. JavaScript 中的異步編程
- 37.異步編程的 Promise
- 38.異步函數
- IX.更多標準庫
- 39.正則表達式(RegExp)
- 40.日期(Date)
- 41.創建和解析 JSON(JSON)
- 42.其余章節在哪里?