跳至主要内容

請說明 JavaScript 中 == 和 === 的差異為何?

== 是鬆散比較運算子、===是嚴格比較運算子,兩者最大的不同:==是當等號兩邊 values 的型別不同時,會強制轉換資料型別與值,而 === 不會。

=== 嚴格比較

必須等號雙邊的值與型別一致,才會回傳 true,如果型別不同,即使值相同,也會回傳 false

== 鬆散比較

== 會當等號運算子兩邊值的型別不同時,會在將兩邊的值進行比較之前,強制轉換型別和值,再進行比較。

常見的強制轉換規則

  • Boolean,String,Number型別比較時會轉換為數字。
  • true 會轉換為 1false 會轉換為 0
  • null == undefined 回傳 true,因為它們被認為是"相等的",即使型別不同。
  • nullundefined 與其他任何值比較(如數字、布林值、字串等)時,會回傳 false
  • 當一個物件與一個原始值進行比較時,會嘗試使用 valueOf 方法將物件轉換為一個原始值。
  • 當一個陣列與一個非陣列值進行比較時,會使用陣列的 toString 方法轉換成字串。

Object.is()

=== 更嚴格的比較,會檢查傳入兩個的值是否為相同值,然後會回傳 Boolean 。 與 === 不同的是:

  • ===會將-0+0 視為相等,但Object.is()視為不同值。
  • ===會將NaNNaN視為不同相等,但Object.is()視為相等。

實例練習1

10. Equal

// This is a JavaScript Quiz from BFE.dev

console.log(0 == false);
console.log("" == false);
console.log([] == false);
console.log(undefined == false);
console.log(null == false);
console.log("1" == true);
console.log(1n == true);
console.log(" 1 " == true);

解題1

console.log(0 == false);

true,因為 false 會被強制型別轉換成 00 == 0 值相等。

console.log("" == false);

true,因為空字串跟 false 會被強制型別轉換成 0

console.log([] == false);

true,因為空陣列會先被轉成空字串,空字串會再轉成 0false 會被轉成 00 == 0 值相等。

console.log(undefined == false);

false,因為 undefined 只會與 null 寬鬆相等。

console.log(null == false);

false,因為 null 只會與 undefined 寬鬆相等。

console.log("1" == true);

true,因為 "1" 會被轉成 1true 會被轉成 11 == 1 值相等。

console.log(1n == true);

true,因為 1n 會從 BigInt 轉成 1true 會被轉成 11 == 1 值相等。

console.log(" 1     " == true);

true,因為 " 1 " 會轉成 1,true 會被轉成 11 == 1 值相等。

實例練習2

24. Equality & Sameness

// This is a JavaScript Quiz from BFE.dev

console.log(0 == "0");
console.log(0 === "0");
console.log(Object.is(0, "0"));

console.log(0 == 0);
console.log(0 === 0);
console.log(Object.is(0, 0));

console.log(0 == -0);
console.log(0 === -0);
console.log(Object.is(0, -0));

console.log(NaN == NaN);
console.log(NaN === NaN);
console.log(Object.is(NaN, NaN));

console.log(0 == false);
console.log(0 === false);
console.log(Object.is(0, false));

解題2

console.log(0 == "0");

true,鬆散比較會強制轉換 "0" 的型別為 00 == 0 值相等。

console.log(0 === "0");

false,因嚴格比較兩邊的型別需相同。

console.log(Object.is(0, "0"));

false,因 Object.is 進行同值嚴格比較,兩個型別不同。

console.log(0 == 0);

true,兩邊值相同。

console.log(0 === 0);

true,兩邊值相同。

console.log(Object.is(0, 0));

true,兩邊值相同。

console.log(0 == -0);

true0-0在 JavaScript 中鬆散比較被認為是相等的。

console.log(0 === -0);

true0-0在 JavaScript 中嚴格比較被認為是相等的。

console.log(Object.is(0, -0));

false,因 Object.is 進行同值嚴格比較認為 0-0 是不相等的。

console.log(NaN == NaN);

false,在 JavaScript 中,NaN(Not-a-Number) 與任何值都不相等,包括它自己。

console.log(NaN === NaN);

false,在 JavaScript 中,NaN(Not-a-Number) 與任何值都不相等,包括它自己。

console.log(Object.is(NaN, NaN));

true,因 Object.is認為 NaNNaN 是相等的。

console.log(0 == false);

true,因為鬆散比較 false 會轉型為 00 == 0 值相等。

console.log(0 === false);

false,因嚴格比較兩邊的型別需相同。

console.log(Object.is(0, false));

false,因兩個值的類型不同。

實例練習3

30. Equal II

// This is a JavaScript Quiz from BFE.dev

console.log([1] == 1);
console.log([1] == "1");
console.log(["1"] == "1");
console.log(["1"] == 1);
console.log([1] == ["1"]);
console.log(new Boolean(true) == 1);
console.log(new Boolean(true) == new Boolean(true));
console.log(Boolean(true) == "1");
console.log(Boolean(false) == [0]);
console.log(new Boolean(true) == "1");
console.log(new Boolean(false) == [0]);
console.log(null == undefined);

解題3

console.log([1] == 1);

true,在鬆散比較下,當一個陣列與一個非陣列值進行比較時,會使用陣列的 toString 方法轉換成字串,[1] 會被轉換為 "1""1"再轉成 11 == 1 值相等。

console.log([1] == "1");

true,在鬆散比較下 [1] 會轉成"1""1"== "1"值相等。

console.log(["1"] == "1");

true,在鬆散比較下 ["1"] 會轉成"1""1"== "1"值相等。

console.log(["1"] == 1);

true,在鬆散比較下 ["1"] 會轉成"1",,"1"再轉成 11 == 1 值相等。

console.log([1] == ["1"]);

false,因為 ["1"][1] 都是陣列,兩個物件的參考的記憶體位置不相同。

console.log(new Boolean(true) == 1);

true,在鬆散比較下,當一個物件與一個原始值進行比較時,JavaScript 會嘗試使用 valueOf 方法將物件轉換為一個原始值,new Boolean(true)轉成truetrue再轉換成11 == 1 值相等。

console.log(new Boolean(true) == new Boolean(true));

false,因為兩個物件相比較時,會檢查兩個物件的參考的記憶體位置是否相同。

console.log(Boolean(true) == "1");

trueBoolean(true) 會返回 truetrue 轉為 1 ,"1" 轉為 1,1 == 1 值相等。

console.log(Boolean(false) == [0]);

trueBoolean(false) 會返回 false[0] 會轉成 "0"false再轉成 0"0"再轉成 00 == 0值相等。

console.log(new Boolean(true) == "1");

truenew Boolean(true) 轉成 true"1" 轉成 1true 再轉成 11 == 1值相等。

console.log(new Boolean(false) == [0]);

false,因為 new Boolean(false)[0] 分別是陣列跟物件,兩個參考的記憶體位置不相同。

console.log(null == undefined);

true,在鬆散比較中 nullundefined 是相等的。