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となり数値比較)