のこのこかずのこ

10年エンジニアやってるけどいまだになんもわからん

JavaScriptで配列と文字列を比較した時の挙動

長年JavaScriptを使っていても、いまだに、基本的なところで「あれ!?」と思う挙動にぶち当たることがあります。

配列(オブジェクト)同士の比較
let array1 = ["a", "b", "c"];
let array2 = ["a", "b", "c"];
console.log(array1 == array2);   // false

配列(オブジェクト)は、中身が同じでも等価ではない。これは経験からなんとなく予想できます。 オブジェクトはデータの参照元(メモリの位置)で比較しているからのようです。ちょっと不便ではあります。

配列と文字列の比較
let array1 = ["a", "b", "c"];
let string1 = "a,b,c";
console.log(array1 == string1);   // true

今回驚いたのはこの2つが等しいことです。当然falseだと思っていました。

等価 (==) - JavaScript | MDN

オペランドの型が異なる場合は、比較前に同じ型に変換を試みます。 オペランドのうちの一方がオブジェクトで、もう一方が数値または文字列である場合は、そのオブジェクトの valueOf() および toString() メソッドを使用してプリミティブに変換を試みます。

ちゃんと書いてありました。配列と文字列を比較する時、配列の方は、toString()でカンマ区切りの文字列となって比較されるみたいです。

let array1 = ["a", "b", "c"];
let string1 = "a,b,c";
console.log(array1 === string1);   // false

厳密演算子だともちろんfalseになります。

厳密等価 (===) - JavaScript | MDN

この演算子と等価 (==) 演算子の最も顕著な違いは、オペランドの型が異なる場合、 == 演算子は比較前に同じ型に変換しようとすることです。

なるほど〜。感覚的には理解してたけど、ちゃんと文章にするとこうなるのですね。 型が違う値を比較しようと思うことが今まであまりなかったからか、知らなかった!(恥)ドキュメントはちゃんと読みましょう。

JavaScriptは今までなんとなく使っていてちゃんと学んだことがなかったので、基礎から体系的に勉強したいな…ということで、この本を購入してみました。勉強します。