JavaScriptにおける暗黙の型変換

2019/03/08更新

目次

TruthyとFalsy

概要

JavaScriptでは、真偽値であるtruefalse以外にも、どのような値でもif文の条件などに使うことができ、真と偽のどちらとして扱われるか決められている。if文や条件演算子の条件部分にそのまま指定したときに、真として扱われるものをTruthyな値、偽として扱われるものをFalsyな値という。!!で真偽値に変換したときの結果と同じであり、Booleanへの暗黙的な型変換と考えることができる。

Falsyな値として、真偽値のfalseの他に、数値の0、空文字列''、未定義値undefined、null値null、非数NaNが定められている。逆にこれ以外のものは基本的に全てTruthyとされる。

型変換時の変化

例えば、trueは、+trueなどとして数値化すると1true+""のようにして文字列化すると"true"という文字列になるが、いずれもTruthyである。ところが、このような型変換によって真偽が変わるものもある。以下は、数値(Number)および文字列(String)に変換したときにどのような値になるかと、それが真偽のどちらになるかの一覧である。

元の値

Numberに変換

Stringに変換

真偽

真偽

真偽

真偽値の真

true

Truthy

1

Truthy

"true"

Truthy

数値の1

1

"1"

文字列の「1」

"1"

空オブジェクト

{}

NaN

Falsy

"[object Object]"

文字列の「0」

"0"

0

"0"

空配列

[]

""

Falsy

空文字

""

Falsy

真偽値の偽

false

"false"

Truthy

数値の0

0

"0"

null

null

"null"

非数

NaN

NaN

"NaN"

未定義値

undefined

"undefined"

  • NumberでFalsyとなるものは、0とNaNだけで、それ以外は全てTruthyである。

  • StringでFalsyとなるものは、空文字列""だけで、それ以外は全てTruthyである。

  • "0"{}[]は、それ自体はTruthyであるが、Number化するとFalsyになる。

  • false0nullNaNundefinedは、それ自体はFalsyであるが、String化すると全てTruthyとなる。

  • 一方、[]は逆に、Truthyであるが、String化するとFalsyとなる。

数値化は、Number()または+演算子を作用させた場合の結果であるが、ビット演算である|0を使うと、{}NaNundefinedも0となる。ただ、Falsyであることには変わりない。

比較演算子における型変換

抽象等価演算子

==!=は等価と不等価をそれぞれ判定する演算子であるが、比較対象の型が異なる場合、比較の前に以下のような暗黙的な型変換が行なわれる。

  1. nullundefinedが比較されている場合は、常にtrueとする。

  2. Boolean値は、事前にNumber(falseなら0trueなら1)に変換する。

  3. Number値とString値が比較されている場合は、String値をNumberに変換してから比較する。

  4. Number値またはString値と、Objectが比較されている場合、Objectはプリミティブ型に変換してから比較する。

  5. これ以外のケースは全て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となり数値比較)

外部リンク