Ruby等からプログラミングを始め、その後JavaScript二触れ合う人は、「===」という比較演算子に馴染みがないことも多い気がします。(私はそうでした。)
なんとなく、「===」は厳密な比較で「==」はもっと緩い比較くらいに捉え、「===」を利用すべきなんだなとは思っていましたが、慣れてきたところでちゃんと理解しておこう、というモチベーションの記事です。
「==」 と 「===」 って何が違うの?
用語のみだと
「==」:等価演算子
「===」:厳密等価演算子
となります。仰々しい名前。ただ、一体何が<厳密>なのか?
両者の違いは、簡単にいうと「型変換をして比較 or しないで比較」 ということになります。
厳密等価演算子「===」について
こちらの方が単純なため、先に記載。
名前の通り、左辺と右辺の値を厳密に比較してくれます。
以下の例は、全て何も出力されません。
if (1 === '1') {
console.log('number と string')
}
if (0 === false) {
console.log('number と boolean')
}
if (null === undefined) {
console.log('null と undifined')
}
結果
// 何も出力されない
上記の通り、1は'1'とは別ですし、0とfalseも別のものです。ですので、非常に直感的な動作をしてくれます。
等価演算子「==」について
こちらが少し厄介です。下に例を示します。
// '1' が numberに変換され、その後 1 と比較される
if (1 == '1') {
console.log('number と string')
}
// falseが 0 に変換され、その後 0 と比較される
if (0 == false) {
console.log('number と boolean')
}
// '0'は0に、falseも0に変換され、比較される
if ('0' == false) {
console.log('string と boolean')
}
// 空配列は""に変換される。
if ([] == '') {
console.log('array と string')
}
// [] -> '' -> 0, false -> 0
if ([] == false) {
console.log('array と boolean')
}
// [1] -> '1' -> 1
if ([1] == 1) {
console.log('array と string')
}
if (null == undefined) {
console.log('null と undifined')
}
実行結果
number と string
number と boolean
string と boolean
array と string
array と boolean
array と string
null と undifined
というように、全て出力されました。
詳細な説明は省きますが、比較演算子「==」を利用し、かつ両辺の値の型が違う場合、値同士をそのまま比較するのではなく、一度型変換のプロセスを挟み、比較してくれます。
※ '1' == '1'など、同じ型の場合はそのまま比較してくれます。
このように、型が違くてもtrueと判定される場面がある、ということです。
(なんとなく、falsyな値と関連しそうです。また調べます。)
予期せぬ動作を防ぐために
よく、「===」を使う方が良い、と聞く(?)と思いますが、上記のように「==」は型が違くても同じものになるよう変換してくれてしまうので、本来はfalseとなって欲しい場面でtrueとなってしまう、ということが発生しやすくなります。
ですので、「===」を使う方が基本的に推奨されているように思います。
ただ、nullとundifindのようなものは同じように扱いたい、というときなどにはもしかしたら有効かもしれません。
が、潜在的なバグを抱えてしまいそうなので、特別な理由がなければ「===」を使っておくことが無難な気がします。なるほど。