メインコンテンツまでスキップ

truthyな値、falsyな値

特定の条件で処理を変えたい

どのような言語でも、ある条件のときは別の処理をさせたいということがあります。むしろ、ない言語はないでしょう。当然、JavaScriptでもそのような機能はあり、ifを使います。

ts
if (employee.isPartTime()) {
// ...
}
ts
if (employee.isPartTime()) {
// ...
}

このときメソッドのisPartTime()は真偽値、つまりboolean型を返すとは誰もが見てもそう思います。

JavaScriptでは、真偽値でなくてもifの対象にできる

ところが、JavaScriptではその限りではありません。JavaScriptではその値(や演算結果)がboolean型である必要はありません。では、どのような値の場合はifブロックを実行し、逆に実行しないのでしょうか。

true, false「のような」値

このようなとき、条件を満たすとされる値のことをtruthyと、また満たさないとされる値のことをfalsyと呼びます。これは英語の真と偽を意味するtruthとfalseにそれぞれ「のような」というニュアンスを表す接尾語のyをつけたものです。

falsyな値

falsyな値から説明します。というのはfalsyな値というのは限られており、それ以外のすべての値がtruthyとなるのでこれだけ覚えてしまえばいいということでもあります。

意味
falseboolean疑値
0number数値の0
-0number数値の-0
NaNnumberNot a Number
0nbigint整数値の0
""string空文字列
nullnullnull
undefinedundefinedundefined

これらの値がifの条件式に入った場合、そのifブロックは実行されません。

truthy, falsyな値で条件分岐することの問題点

これらの値を使ってifの条件式にすること自体は可能なのですが、同時に意図しない挙動を含むことがあるので使う際は注意したほうがよいでしょう。たとえば、次の例は配列にあるnullを取り除くつもりでコードを書きましたが、意図しない結果になります。

ts
const array = [null, 3, 0, null, 1, 2];
 
console.log(array.filter((n) => n));
[3, 1, 2]
ts
const array = [null, 3, 0, null, 1, 2];
 
console.log(array.filter((n) => n));
[3, 1, 2]

array.filter()でfalsyな値を取り除いた結果、nullはともかくnumber型でfalsyな値である0までもが取り除かれてしまいました。

このような事態にならないために

意図しない分岐を避けるためには、truthy, falsyの値を直接boolean型として使うのではなく、ちゃんとtrue, falseの値を返すようにします。

ts
const array = [null, 3, 0, null, 1, 2];
 
console.log(array.filter((n) => n !== null));
[3, 0, 1, 2]
ts
const array = [null, 3, 0, null, 1, 2];
 
console.log(array.filter((n) => n !== null));
[3, 0, 1, 2]

TypeScript ESLintにもこの問題のためのオプションがある

TypeScriptのeslintにもifブロックでboolean型以外が与えられると警告を発するオプションがあります。

strict-boolean-expression

しかしながら、このオプションでもarray.filter()の例では警告を発しないので気をつける必要があります。