在 JS 有兩個 equality operator :
3 === 3.0; // true
"yes" === "yes"; // true
null === null; // true
false === false; // true
42 === "42"; // false
"hello" === "Hello"; // false
true === 1; // false
0 === null; // false
"" === null; // false
null === undefined; // false
嚴格相等 (strict equality) 不僅 value 要一樣,連 type 也要一樣,否則不會成立。嚴格相等禁止任何 value type 的轉換 (coercion),因此 type 不一樣,在嚴格相等的情形會回傳 false。
上面的例子都是 primitive values,我們來討論 object values:
[ 1, 2, 3 ] === [ 1, 2, 3 ] // false
{ name: 'Cheryl } === { name: 'Cheryl' } // false
( x => x*2 ) === ( x => x*2 ) // false
在做 equality check 的時候,會從兩個層面下去考量
通常要做 equality check 的是 object values 時,會從 content-aware 的層面下去對比 (aka structural equality),然而 JS 定義 === 使用 identity equality 來比對 object values,而不是 contents-aware 來比對。
在 JS,object values 都是以 reference 的形式存在,不論是定義一個 object values,或是 copy 一個 object values,都是 reference,請看例子
var x = [ 1, 2, 3 ];
var y = x;
// assignment is by reference-copy, so
// y references the **same** array as x,
// not another copy of it.
y === x; // true
y === [ 1, 2, 3 ]; // false
x === [ 1, 2, 3 ]; // false
因為 object values 是 call by reference,所以 x assign y 的是 x 初始的 array (可以想成 x 和 y 指向同一個 object,他們都 reference 同一個 object)
不論是 x === [ 1, 2, 3 ], 或者 y === [ 1, 2, 3 ] 都會回傳 fail。[ 1, 2, 3 ] 看起來與 x 初始的 value 一模一樣,但其實 [ 1, 2, 3 ] 是新的 array,在 comparison 裡,object values 的 contents, structure 並不重要,重要的是 reference identity。
說這麼多,總結一下今天的學習:
[ 參考 ]