なぜfalseになる?JavaScript数値が腑に落ちた日
今日はJavaScriptの数値と型変換まわりを学び直しました。
実務でフォームの値やAPIレスポンスを扱うときに「数値だと思っていたら文字列だった」というズレを何度か経験したのが背景です。
以下が今回のコードの抜粋です。
console.log(23 === 23.0);
console.log(0.1 + 0.2);
console.log(0.1 + 0.2 === 0.3);
// Conversion
console.log(+'23');
console.log(+'23');
// Parsing
console.log(Number.parseInt('30px', 10));
console.log(Number.parseInt('e23', 10));
console.log(Number.parseInt(' 2.5rem '));
console.log(Number.parseFloat(' 2.5rem '));
// Check if value is Nan
console.log(Number.isNaN(20));
console.log(Number.isNaN('20'));
console.log(Number.isNaN(+'20X'));
console.log(Number.isNaN(23 / 0));
// Checking if value is number
console.log(Number.isFinite(23));
console.log(Number.isFinite('20'));
console.log(Number.isFinite(+'20X'));
console.log(Number.isFinite(23 / 0));
console.log(Number.isInteger(23));
console.log(Number.isInteger(23.0));
console.log(Number.isInteger(23 / 0));今日やったこと
今日はJavaScriptにおける数値の扱いと型変換を一通り整理しました。
特に比較演算とNumber系メソッドの挙動を、実際にconsole.logしながら確認しています。
やってみて気づいたこと
まず次のコードです。
console.log(23 === 23.0);これはtrueになります。
JavaScriptでは数値はすべて浮動小数点数として扱われており、整数と小数を内部的に区別していないことを改めて意識しました。
一方でこちらは少し怖い挙動です。
console.log(0.1 + 0.2 === 0.3);結果はfalseになります。
0.1 + 0.2自体を出力すると、計算誤差がそのまま現れているのがわかります。
「比較しているコード自体は正しそうなのに、結果がズレる」という点は実装時に特に注意が必要だと感じました。
実装目線でのこだわり
型変換では次の書き方を使っています。
console.log(+'23');+を数値の前につけると、その値を数値として解釈し直すという意味になります。そのため、このコードはNumber('23')と同じ結果になります。
短く書けるうえに「ここで文字列を数値に変換している」という処理の区切りが、コードを見ただけで分かるのが理由です。
NaNチェックでは次のコードを確認しました。
console.log(Number.isNaN(+'20X'));グローバルのisNaNではなくNumber.isNaNを使うことで、本当にNaNだけを安全に判定できます。
数値判定ではこちらも重要です。
console.log(Number.isFinite(23 / 0));Infinityを数値として通してしまわないために、実務ではisFiniteを使ったほうがバリデーションの意図が明確になります。
まとめ
知っているつもりの内容でも、コードとして並べて確認すると理解の浅さに気づきます。
学び直しは遠回りに見えて、実装の判断を早くしてくれる土台づくりだと感じました。
普段はWebまわりの制作をしています。
たとえば、会社のホームページをそろそろ作りたい、昔作ったサイトを今っぽくしたい、といったご相談も大歓迎です。
気になったら気軽に声をかけてくださいね。
ここまで読んでいただき、ありがとうございました。同じように学び直している方の参考になればうれしいです。
