LoginSignup
2
2

JavaScriptの親切過ぎる型変換

Last updated at Posted at 2022-04-14

概要

jsの比較演算子に関する仕様です。
間違って配列と数値を比較してしまいましたが、処理が通ったので驚きました。

// 比較A
1 == [1] // true
// 比較B
1 === [1] // false
// 比較C
'1' === [1] // false

種明かし

比較する値がオブジェクトの場合、手順を追ってプリミティブ型に変換した上で比較される。

解説

stack overflowでも解説をみつけましたが、概要にのせた中の比較Aを例に解説します。
解説中にプリミティブ型とオブジェクト型が出てくるので、分からない方は以下を参考に

プリミティブ型とオブジェクト型
https://qiita.com/makotoo2/items/9566cebf205ef8b42505

// 比較A
1 == [1]

1. まず、右辺がオブジェクトなので、プリミティブ型に変換。
Arrayの場合、toStringメソッドによってstringに変換。

1 == '1'

2. それでもまだ左右で型が違うので、文字列をNumberオブジェクトに変換。

1 == Number('1')

3. 右辺がオブジェクトなので、再度プリミティブ型に変換。
Numberの場合、valueOfメソッドによってintに変換

1 == 1

4. 両辺の型が揃ったので、比較し結果を返す

true

比較Bのように、比較演算子が=== の場合、1の操作までで終わり、型を揃える操作は行われずfalseとなります。
厳密な手順は少し違いますが、正確なのは上記のstack overflowでもChristophさんがおっしゃっているように、jsの規格(ECMA-spec)に載っています。

3rd edition
ECMA-spec
(P67の11.9.3 The Abstract Equality Comparison Algorithm)

また、最新版でも同様

11th edition
ECMA-spec
(P129の7.2.19 Abstract Equality Comparison)

感想

さすがjsって感じの親切さですね。もちろん、この仕様に頼るとバグの元になる上に、読む人に理解されづらいので、自身のコードは別の書き方に修正しました。
また、jsの規格も初めて読みましたが結構簡単な英語で書かれているので、読みやすかったです。

2
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2