型を変換する
このレッスンで分かること
Number(値)で数値へ、String(値)で文字列へ、自分の手で変換できます+は片方が文字列だと連結になるので、計算する前に型をそろえます
数字に見えるのに計算できない
入力欄から届いた値は、見た目が数字でも文字列です。そのまま計算しようとすると、期待とは違う結果になります。
JavaScript
const viewsText = "120";
console.log(viewsText + 10); // "12010" 連結されてしまう
console.log(viewsText - 10); // 110 引き算はできる足し算だけが連結になり、引き算は数として計算されます。+ は文字列の連結にも使う記号なので、片方が文字列だと連結が優先されます。- には連結の意味が無いので、JavaScript が文字列を数値に直してから計算します。
この勝手に変換される動きを 暗黙の型変換 と呼びます。便利に見えますが、どちらに転ぶかを読み手が予測できません。変換したい場所で自分から変換するほうが安全です。
Number で数にそろえる
JavaScript
console.log(Number("120") + 10); // 130
console.log(Number(" 5 ")); // 5 前後の空白は無視される
console.log(Number("3年")); // NaN 数として読めないNumber() は値の全体を数として読もうとします。数として読めない文字が 1 つでも混ざると NaN になります。NaN は Not a Number の略で、数値型でありながら数として意味を持たない特別な値です。計算に混ざると結果もすべて NaN になるため、変換の失敗に気付かないまま画面に NaN と表示される事故が起きます。
反対に、数値を文面に混ぜたいときは String() を使います。String() はどんな値でも文字列にできるので、Number() のように失敗することがありません。
| 式 | 結果 | 覚えどころ |
|---|---|---|
Number("3") | 3 | 素直に変換される |
Number(" 5 ") | 5 | 前後の空白は無視される |
Number("") | 0 | 空文字は 0 になる |
Number("3年") | NaN | 余計な文字があると失敗 |
Number(null) | 0 | null は 0 として扱われる |
Number(undefined) | NaN | undefined は数にできない |
String(3) | "3" | どんな値でも文字列にできる |
String(true) | "true" | 真偽値も文字になる |
Number("") が 0 になるところは特に注意が要ります。未入力のまま計算が通ってしまうため、入力していないのに 0 として扱われた、という不具合の原因になります。
変換は入口で 1 回だけ
使う直前で毎回 Number() を書くと、同じ変換が処理のあちこちに散らばります。1 か所でも書き忘れると、そこだけ文字列のまま計算されて連結が起きます。値を受け取った直後に変換し、変換後の値に名前を付けておけば、以降の行では型を気にせずに済みます。
JavaScript
const viewsText = "120";
const views = Number(viewsText); // ここから先は数値として扱える
console.log(views + 10);
console.log(views * 2);覚え方 外から入ってきた値は、受け取った直後に型をそろえます。この一手間を入口で済ませておくと、後の処理が型を気にせずに書けます。
よくある間違い
変換せずに足してしまうのが 1 つ目です。
JavaScript
const countText = "8";
console.log(countText + 2); // "82" 期待は 10Number(countText) + 2 と書けば 10 になります。
2 つ目は、NaN になったことに気付かないケースです。
JavaScript
console.log(Number("8件") + 2); // NaN 画面にも NaN と出るNaN は他の値と比べても等しくならない特殊な値なので、判定には Number.isNaN() を使います。まずは、変換は失敗しうるという前提を持っておいてください。
要件
- 関数名は nextYearLabel、引数は yearsText (文字列または数値) の 1 つ
- Number で数値に変換してから 1 を足す
- 戻り値は
4 年目の形の文字列。数値を String で文字列にしてから連結する