等価であるということ
どの言語でも、値を比較することがあります。JavaScriptにおいて等価の演算子は等価演算子(==
)と厳密等価演算子(===
)のふたつがあります。等しいことを判定するための演算子がふたつ存在するのは、必ずしも同じものを等しいとはしないためです。
===
で等価であるということ
厳密と名がついているとおり、この演算子での等価は型が等しく、かつ値が等しいことを指します。この動作は等価演算子がひとつしかない言語の==
と同じものです。
次の例は同然ではないかと思うかもしれません。
ts
console .log (null ===undefined );console .log (0 === 0n);console .log (0 === "0");
ts
console .log (null ===undefined );console .log (0 === 0n);console .log (0 === "0");
0n
はnumber型ではなくbigint型のことです。
📄️ bigint型
==
で等価であるということ
ただの等価演算子という名ですが、こちらは型が異なっていても同じと見なすことがあります。厳密には、値の型が異なる場合は型の変換ができないか試みてから値が等しいかを比較します。
ts
console .log (null ==undefined );console .log (0 == 0n);console .log (0 == "0");console .log (0 == "");console .log (0 == false);console .log ("0" == false);console .log ("" == false);
ts
console .log (null ==undefined );console .log (0 == 0n);console .log (0 == "0");console .log (0 == "");console .log (0 == false);console .log ("0" == false);console .log ("" == false);
"0" == false
, "" == false
は戻り値がtrue
ですが、だからとはいえ"" == "0"
はfalse
となるので注意が必要です。
いつ==
と===
を使うのか、使い分けるのか
意図しない動作を避けるという観点においては、厳密等価演算子(===
)を常用し、必要なタイミングで等価演算子を使うといいでしょう。とはいえその必要なタイミングの多くはx == null
です。これは変数xがnull
かundefined
のときにtrue
を返します。
等価であることを気をつける値
安易に等値比較をするとfalse
になってしまい、注意が必要な値があります。
NaN
- symbol型の値
- object型の値
NaN
NaN
はnumber型の値ですが、どの値と比較をしてもfalse
を返します。たとえそれがNaN
同士の比較であってもfalse
を返します。
ts
console .log (NaN ==NaN );console .log (NaN ===NaN );
ts
console .log (NaN ==NaN );console .log (NaN ===NaN );
この性質を使うとその値がNaN
であるかどうかを判定することができます。
ts
functionisNaN (value : unknown): boolean {returnvalue !==value ;}console .log (isNaN (1));console .log (isNaN (NaN ));
ts
functionisNaN (value : unknown): boolean {returnvalue !==value ;}console .log (isNaN (1));console .log (isNaN (NaN ));
symbol型の値
symbol型は、たとえ同じdescription(第1引数)が同じ値同士を比較しても、まったく同じ変数名を参照しない限りfalse
を返します。
ts
console .log (Symbol ("piano") ==Symbol ("piano"));console .log (Symbol ("piano") ===Symbol ("piano"));constsym =Symbol (2);console .log (sym ===sym );
ts
console .log (Symbol ("piano") ==Symbol ("piano"));console .log (Symbol ("piano") ===Symbol ("piano"));constsym =Symbol (2);console .log (sym ===sym );
object型の値
object型は、同じプロパティと値のペアの比較をしても、まったく同じ変数名を参照しない限りfalse
を返します。これはオブジェクトについて理解がある人にとっては当然の挙動です。
ts
console .log ({} == {});console .log ({} === {});console .log ({age : 18 } == {age : 18 });console .log ({equipment : "glasses" } === {equipment : "glasses" });constobj = {hair : "blond" };console .log (obj ===obj );
ts
console .log ({} == {});console .log ({} === {});console .log ({age : 18 } == {age : 18 });console .log ({equipment : "glasses" } === {equipment : "glasses" });constobj = {hair : "blond" };console .log (obj ===obj );