唯物是真 @Scaled_Wurm

プログラミング(主にPython2.7)とか機械学習とか

JavaScriptの==による配列の等価性比較の挙動クイズ

JavaScriptではイコール2つによる等価性の比較は、意図しない型の変換が起こるので使わないほうがよいと言われています
TwitterでJavaScriptで[] == ![]の挙動がおもしろい、という話を見かけたので調べてみました

というわけで突然ですが問題です。以下の比較について結果がどうなるか一瞬考えてみてください

  • [] == ![]
  • [0] == false
  • [1] == true
  • [1] == [1]
  • [1, 2] == true
  • [1, 2] == false

ヒント: ==の挙動は以下の表のような動きをします

MDNのドキュメントの表を拝借
等価性の比較とその使いどころ - JavaScript | MDN
f:id:sucrose:20170312233407p:plain

正解

f:id:sucrose:20170312232927p:plain

解説

MDNのドキュメントを読んだなんとなくの理解で解説しますが、間違ってたらコメントなどで指摘してください

[] == ![]

まず![]の部分ですがBoolean([])trueになるので、![]falseになります
配列はオブジェクトなので、表を見るとToPrimitive([]) == ToNumber(false)という比較になります
[].toString()は空文字列に変換されるので、つまりだいたい'' == false0 == 0と同じことになります

[0] == false, [1] == true

上のと同様に[0].toString()'0'[1].toString()'1'になるので、それぞれの比較結果はtrueになります

[1] == [1]

オブジェクト同士の比較の場合、完全に同じオブジェクトを指しているかどうかで判定されるので、内容が同じでもこの比較の結果はfalseになります

[1, 2] == true, [1, 2] == false

まず左辺が文字列に変換されて'1,2'になります
次に数値への変換が起こってNaN == 1の比較になるので、比較結果はfalseになります

まとめ

  • Boolean([])true
  • ==の左辺か右辺に[]が来るとだいたいfalseと同じ
  • ==による比較は難しい