結構ハマっている人がいるので、整理がてらメモ。
JavaScriptでは変数は型を持たないが、値がデータ型を持つ。
例えば以下のプログラムでは、数値(number)が文字列(string)としてキャストされて文字列結合が行われる。
例1: demo1.js
let hoge = 128; // number
let fuga = 'abc'; // string
let result = hoge + fuga; // string
console.log(result); // 文字列として [128abc] が出力される
適当に扱っていてもよしなに扱われることが多いが、理解していないと思わぬ落とし穴にハマることがあるので注意。
特に多く見かけるのが真偽値の扱い。
JavaScriptでは[null, undefined, numberの0, booleanのfalse]などが偽の値として扱われる。
例2: demo2.js
console.log(null ? '真': '偽'); // 偽
console.log(undefined ? '真': '偽'); // 偽
console.log(false ? '真': '偽'); // 偽
値が代入されているか(nullかどうか)を期待したつもりでも、numberの0やbooleanのfalseが代入された場合には偽になってしまう。
これを防ぐためにはそのまま値を真偽値に使うのではなく、[nullかどうか]あるいは[undefinedかどうか]で条件を考慮してやる必要がある。
また逆にnumberの0やbooleanのfalseを期待していたつもりでも、データ型がstringだった場合には真になってしまう。
例3: demo3.js
console.log("0" ? '真': '偽'); // 真
console.log("false" ? '真': '偽'); // 真
最近はJSON文字列をパースして使う場面も多いので、思わぬところで落とし穴にハマらないようにしたいところ。
例4: demo4.js
let json = '{"hoge":"0","fuga":0}';
let data = JSON.parse(json);
console.log(data['hoge'] ? '真': '偽'); // 真
console.log(data['fuga'] ? '真': '偽'); // 偽
ちなみに2つのオペランドを比較する際、データ型まで厳格にチェックしたい場合には[==(等価)]ではなく[===(厳密等価)]を使う。
例5: demo5.js
console.log(0 == '0' ? '真': '偽'); // [==(等価)]の場合、真
console.log(0 === '0' ? '真': '偽'); // [===(厳密等価)]の場合、偽
有耶無耶に使っていると混乱するので、注意しておこう。