+
)==
與 ===
==
和 !=
)===
和 !==
)===
更嚴格:Object.is()
JavaScript 的運算子可能看起來很奇怪。有了以下兩個規則,它們就更容易理解
如果運算子取得的運算元類型不正確,它很少會引發例外。相反,它會強制轉換(自動轉換)運算元,以便它可以處理它們。我們來看兩個例子。
首先,乘法運算子只能處理數字。因此,它會在計算結果之前將字串轉換為數字。
> '7' * '3'21
其次,用於存取物件屬性的方括號運算子 ([ ]
) 只能處理字串和符號。所有其他值都會強制轉換為字串
const obj = {};
'true'] = 123;
obj[
// Coerce true to the string 'true'
.equal(obj[true], 123); assert
如前所述,大多數運算子僅適用於原始值。如果運算元是物件,它通常會強制轉換為原始值,例如
> [1,2,3] + [4,5,6]'1,2,34,5,6'
為什麼?加號運算子會先強制轉換其運算元為原始值
> String([1,2,3])'1,2,3'
> String([4,5,6])'4,5,6'
接下來,它會串接兩個字串
> '1,2,3' + '4,5,6''1,2,34,5,6'
+
)加號運算子在 JavaScript 中的工作方式如下
字串模式讓我們可以使用 +
來組合字串
> 'There are ' + 3 + ' items''There are 3 items'
數字模式表示如果兩個運算元都不是字串(或會變成字串的物件),則所有內容都會強制轉換為數字
> 4 + true5
Number(true)
是 1
。
一般指定運算子用於變更儲存位置
= value; // assign to a previously declared variable
x .propKey = value; // assign to a property
obj= value; // assign to an Array element arr[index]
變數宣告中的初始化值也可以視為指定的一種形式
const x = value;
let y = value;
JavaScript 支援下列指定運算子
+= -= *= /= %=
[ES1]
+=
也可用于字串串接**=
[ES2016]&= ^= |=
[ES1]<<= >>= >>>=
[ES1]||= &&= ??=
[ES2021]邏輯指定運算子的運作方式與其他複合指定運算子不同
指定運算子 | 等同於 | 僅在 a 為 |
---|---|---|
a ||= b |
a || (a = b) |
假值 |
a &&= b |
a && (a = b) |
真值 |
a ??= b |
a ?? (a = b) |
空值 |
為什麼 a ||= b
等同於下列表達式?
a || (a = b)
為什麼不等於這個表達式?
a = a || b
前一個表達式有 短路運算 的好處:只有在 a
評估為 false
時才會評估指定。因此,只有在必要時才會執行指定。相反地,後一個表達式總是會執行指定。
有關 ??=
的更多資訊,請參閱 §14.4.5「空值合併指定運算子 (??=
) [ES2021]」。
對於 || && ??
以外的運算子 op
,下列兩種指定方式是等同的
myvar op= value
myvar = myvar op value
例如,如果 op
是 +
,則我們會得到運算子 +=
,其運作方式如下。
let str = '';
+= '<b>';
str += 'Hello!';
str += '</b>';
str
.equal(str, '<b>Hello!</b>'); assert
==
與 ===
JavaScript 有兩種相等性運算子:寬鬆相等性 (==
) 和嚴格相等性 (===
)。建議總是使用後者。
==
和 ===
的其他名稱
==
也稱為雙等號。它在語言規範中的正式名稱為 抽象相等比較。===
也稱為三等號。==
和 !=
)寬鬆相等是 JavaScript 的怪癖之一。它經常強制轉換運算元。其中一些強制轉換是有意義的
> '123' == 123true
> false == 0true
其他則不然
> '' == 0true
如果(且僅當!)另一個運算元為原始值時,物件會強制轉換為原始值
> [1, 2, 3] == '1,2,3'true
> ['1', '2', '3'] == '1,2,3'true
如果兩個運算元都是物件,則只有它們是同一個物件時才相等
> [1, 2, 3] == ['1', '2', '3']false
> [1, 2, 3] == [1, 2, 3]false
> const arr = [1, 2, 3];
> arr == arrtrue
最後,==
認為 undefined
和 null
相等
> undefined == nulltrue
===
和 !==
)嚴格相等從不強制轉換。只有當兩個值具有相同的類型時,它們才相等。讓我們重新檢視我們先前與 ==
運算元的互動,看看 ===
運算元做了什麼
> false === 0false
> '123' === 123false
物件僅當另一個值是同一個物件時才相等
> [1, 2, 3] === '1,2,3'false
> ['1', '2', '3'] === '1,2,3'false
> [1, 2, 3] === ['1', '2', '3']false
> [1, 2, 3] === [1, 2, 3]false
> const arr = [1, 2, 3];
> arr === arrtrue
===
運算元不認為 undefined
和 null
相等
> undefined === nullfalse
我建議始終使用 ===
。它使您的程式碼更容易理解,並讓您不必考慮 ==
的怪癖。
讓我們看看 ==
的兩個使用案例,以及我建議的替代方案。
==
的使用案例:與數字或字串比較==
讓您可以檢查值 x
是否為數字或該數字作為字串,只需進行一次比較
if (x == 123) {
// x is either 123 or '123'
}
我比較喜歡以下兩個替代方案
if (x === 123 || x === '123') ···
if (Number(x) === 123) ···
您也可以在第一次遇到 x
時將其轉換為數字。
==
的使用案例:與 undefined
或 null
比較==
的另一個使用案例是檢查值 x
是否為 undefined
或 null
if (x == null) {
// x is either null or undefined
}
此程式碼的問題在於您無法確定某人是否打算這樣寫,或者他們是否打錯字,而意思是 === null
。
我比較喜歡以下兩個替代方案
if (x === undefined || x === null) ···
if (!x) ···
第二種替代方案的缺點是它接受除了 undefined
和 null
以外的值,但這是 JavaScript 中一個根深蒂固的模式(將在 §15.3「基於真值性的存在檢查」 中詳細說明)。
以下三個條件也大致相等
if (x != null) ···
if (x !== undefined && x !== null) ···
if (x) ···
===
更嚴格:Object.is()
方法 Object.is()
比較兩個值
> Object.is(123, 123)true
> Object.is(123, '123')false
它比 ===
更嚴格。例如,它將 NaN
(涉及數字運算的錯誤值)視為等於它自己
> Object.is(NaN, NaN)true
> NaN === NaNfalse
這偶爾會很有用。例如,您可以使用它來實作陣列方法 .indexOf()
的進階版本
const myIndexOf = (arr, elem) => {
return arr.findIndex(x => Object.is(x, elem));
; }
myIndexOf()
會在陣列中找到 NaN
,而 .indexOf()
則不會
> myIndexOf([0,NaN,2], NaN)1
> [0,NaN,2].indexOf(NaN)-1
結果 -1
表示 .indexOf()
無法在陣列中找到其引數。
運算子 | 名稱 |
---|---|
< |
小於 |
<= |
小於或等於 |
> |
大於 |
>= |
大於或等於 |
JavaScript 的排序運算子(表 3)適用於數字和字串
> 5 >= 2true
> 'bar' < 'foo'true
<=
和 >=
基於嚴格相等性。
排序運算子不適用於人類語言
排序運算子不適用於比較人類語言中的文字,例如,涉及大小寫或重音時。詳情說明於 §20.6「比較字串」。
以下運算子在本指南的其他章節中涵蓋
??
)接下來的兩個小節討論兩個很少使用的運算子。
逗號運算子有兩個運算元,會評估它們並傳回第二個運算元
> 'a', 'b''b'
有關此運算子的更多資訊,請參閱 Speaking JavaScript。
void
運算子void
運算子會評估其運算元並傳回 undefined
> void (3 + 2)undefined
有關此運算子的更多資訊,請參閱 Speaking JavaScript。
測驗
請參閱 測驗應用程式。