JavaScriptにおける暗黙の型変換
2019/03/08更新
目次
TruthyとFalsy
概要
JavaScriptでは、真偽値であるtrue
とfalse
以外にも、どのような値でもif文の条件などに使うことができ、真と偽のどちらとして扱われるか決められている。if文や条件演算子の条件部分にそのまま指定したときに、真として扱われるものをTruthyな値、偽として扱われるものをFalsyな値という。!!
で真偽値に変換したときの結果と同じであり、Booleanへの暗黙的な型変換と考えることができる。
Falsyな値として、真偽値のfalse
の他に、数値の0
、空文字列''
、未定義値undefined
、null値null
、非数NaN
が定められている。逆にこれ以外のものは基本的に全てTruthyとされる。
型変換時の変化
例えば、true
は、+true
などとして数値化すると1
、true+""
のようにして文字列化すると"true"
という文字列になるが、いずれもTruthyである。ところが、このような型変換によって真偽が変わるものもある。以下は、数値(Number)および文字列(String)に変換したときにどのような値になるかと、それが真偽のどちらになるかの一覧である。
元の値 | Numberに変換 | Stringに変換 | ||||
---|---|---|---|---|---|---|
値 | 真偽 | 値 | 真偽 | 値 | 真偽 | |
真偽値の真 |
| Truthy | 1 | Truthy |
| Truthy |
数値の1 | 1 |
| ||||
文字列の「1」 |
| |||||
空オブジェクト |
|
| Falsy |
| ||
文字列の「0」 |
| 0 |
| |||
空配列 |
|
| Falsy | |||
空文字 |
| Falsy | ||||
真偽値の偽 |
|
| Truthy | |||
数値の0 | 0 |
| ||||
null |
|
| ||||
非数 |
|
|
| |||
未定義値 |
|
|
NumberでFalsyとなるものは、0と
NaN
だけで、それ以外は全てTruthyである。StringでFalsyとなるものは、空文字列
""
だけで、それ以外は全てTruthyである。"0"
、{}
、[]
は、それ自体はTruthyであるが、Number化するとFalsyになる。false
、0
、null
、NaN
、undefined
は、それ自体はFalsyであるが、String化すると全てTruthyとなる。一方、
[]
は逆に、Truthyであるが、String化するとFalsyとなる。
数値化は、Number()
または+
演算子を作用させた場合の結果であるが、ビット演算である|0
を使うと、{}
、NaN
、undefined
も0となる。ただ、Falsyであることには変わりない。
比較演算子における型変換
抽象等価演算子
==
と!=
は等価と不等価をそれぞれ判定する演算子であるが、比較対象の型が異なる場合、比較の前に以下のような暗黙的な型変換が行なわれる。
null
とundefined
が比較されている場合は、常にtrue
とする。Boolean値は、事前にNumber(
false
なら0
、true
なら1
)に変換する。Number値とString値が比較されている場合は、String値をNumberに変換してから比較する。
Number値またはString値と、Objectが比較されている場合、Objectはプリミティブ型に変換してから比較する。
これ以外のケースは全て
false
とする。
参考:11.9.3 The Abstract Equality Comparison Algorithm
これを理解していれば、以下のような結果は全て納得できる。
false == '0' // true(false→0、'0'→0) false == '' // true(false→0、''→0) false == [] // true(false→0、[]→''→0) false == [[[]]] // true(false→0、[[[]]]→[['']]→['']→''→0) false == 'false' // false(false→0、'false'→NaN) ![] == [] // true(![]→false→0、[]→''→0) !'0' == '0' // true(!'0'→false→0、'0'→0)
また、これによると、その値がTruthy(またはFalsy)だからといって、== true
(または== false
)などとしても必ずしもtrue
にならないため、注意が必要となる。
const x = '0'; const a = x ? true : false; // '0'はTruthyのため、aはtrueとなる。 const b = x == true ? true : false; // '0'→0、true→1と変換されるため、bはfalseとなる。
関係演算子
>
、<
、>=
、<=
は数値や辞書順の大小を比較する演算子であるが、こちらも比較の前に型変換が行われる。まず、プリミティブ型への変換が試みられ、双方ともStringとなった場合のみ辞書順の比較となり、それ以外の場合はNumberへ変換されてから比較される。
'2' > '10' // true(辞書順比較) '2' > 10 // false('2'→2となり数値比較) true >= 'true' // false(true→1、'true'→NaNとなり数値比較) 0 > [] // false([]→''→0となり数値比較) '0' > [] // true([]→''となり辞書順比較) 1 > undefined // false(undefined→NaNとなり数値比較) 1 > null // true(null→0となり数値比較)