? :
)x && y
)、Or(x || y
)
x && y
)||
)!
)基本類型布林值包含兩個值 – false
和 true
> typeof false'boolean'
> typeof true'boolean'
“轉換為 [類型]” 的含義
“轉換為 [類型]” 是“將任意值轉換為 [類型] 類型的值”的簡稱。
以下三種方式可以將任意值 x
轉換為布林值。
Boolean(x)
最具描述性;推薦使用。
x ? true : false
使用條件運算子(說明詳見本章後面的內容)。
!!x
使用邏輯 Not 運算子(!
)。此運算子將其運算元強制轉換為布林值。再次應用它以獲取非否定結果。
表 4 說明了如何將各種值轉換為布林值。
x |
Boolean(x) |
---|---|
undefined |
false |
null |
false |
布林值 | x (不變) |
數字 | 0 → false ,NaN → false |
其他數字 → true |
|
bigint | 0 → false |
其他數字 → true |
|
字串 | '' → false |
其他字串 → true |
|
符號 | true |
物件 | 永遠是 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
)、Or (x || y
)二元邏輯運算子 &&
和 ||
是 值保留 和 短路。
值保留 表示運算元被解釋為布林值,但未變更地傳回
> 12 || 'hello'12
> 0 || 'hello''hello'
短路 表示如果第一個運算元已決定結果,則不會評估第二個運算元。唯一其他會延遲評估其運算元的運算子是條件運算子。通常,所有運算元都會在執行運算之前評估。
例如,邏輯 And (&&
) 如果第一個運算元為假值,就不會評估其第二個運算元
const x = false && console.log('hello');
// No output
如果第一個運算元為真值,則會執行 console.log()
const x = true && console.log('hello');
// Output:
// 'hello'
x && y
)表達式 a && b
(「a
And 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
測驗
請參閱 測驗應用程式。