プログラミング

[JavaScript] number 型と string 型の違いでハマった話とその対処法

絶対に値が一緒なハズなのに、なんで処理が通らないんだ…

こんにちは!

以前 JavaScript で処理を書いているときに、if 文の条件式の中で値Aと値Bを比較して処理させようと思ったんですが、

値Aと値Bが絶対に同じ値なのに処理が全然通らない!なぜなぜー?

となって結構時間を溶かしてしまったことがあったので、なぜそのようなことが起こったのか、ということとその対処法について考えてみたいと思います。

ということで今回は、

[JavaScript] number 型と string 型の違いでハマった話とその対処法

についてまとめたいと思います。

前回ブログはこちらから↓

結論 単なる型の違いです(!)

もう結論かよ、って感じですが、

単純に number 型と string 型の違いでした。(初歩……)

両者の型が違うので値が同じように見えるけど、厳密比較で条件式を書くと弾かれるという。。

試しにデバッグすると number 型と string 型がどのように表示されるのか見てみましょう。

const string = '1'; // string 型の変数を定義
const number = 1; // number 型の変数を定義

if(string == number){ // ①等価演算子を使用した場合
  console.log('同じだよ');
}else{
  console.log('同じじゃないよ');
}

if(string === number){ // 厳密等価演算子を使用した場合
  console.log('同じだよ');
}else{
  console.log('同じじゃないよ');
}

等価演算子(==)を使用した場合

等価演算子は、2つのオペランドが等しいことを検査し、オペランドの方が違った場合は勝手に型変換してくれちゃう親切なような親切じゃないようなヤツです。

オペランドって何?と思った方はこちらの記事をご参考ください↓

よって、①は console に「同じだよ」と表示されます。

厳密等価演算子(===)を使用した場合

厳密等価演算子は、オペランドの型まで厳密にチェックし、型が異なる場合でも型変換はされません。

よって、➁は console に「同じじゃないよ」と表示されます。

デバッグ時の表示の違い

変数の中身を見てみると、 number 型の場合は数字だけ、と string 型の場合は「” “」で囲んでありますね。

number 型↓

string 型↓

知ってれば、「あぁこれ型違うんや」ってすぐ分かるんですけど、

ハマってた時は、どっちも同じやん!なんでなんでーってなってました。。。(恥ずかし)

実はこういうことって誰も教えてくれなかったりするよね。

(え?みなさん言われなくてもそんなこと分かるってか、、、)

そもそもなんでこんなことが起こったか

PDO の仕様?

MySQL で PDO を使ってテーブルから int 型の値を取得した際に、PDO の仕様で全部 string 型に変換されるということがあるみたいです…

なので DB 上は、int/tinyint 型のデータを引っ張ってきているつもりでも、全部 string 型に自動変換されてしまっている場合があるってことなんですね。。

JavaScript の fetch を使ってデータを取ってきたときに全部 string 型になっててアレーって思ったときがありました。。

紛らわしーーーー。

対処法

parseInt – string 型から number 型への変換 –

parseInt を使用して、string 型から number 型へ変換します。こうすれば、厳密比較演算子(===)で比較しても ‘同じだよ’ の分岐に入りますね。

const string = '1'; // string 型の変数を定義
const number = 1; // number 型の変数を定義
if(parseInt(string, 10) === number){
  console.log('同じだよ');
}else{
  console.log('同じじゃないよ');
}

// 結果→ console には '同じだよ' と表示されます

parseInt の第二引数には基数を指定します。

2 から 36 までの整数で、string の基数 (数学的記数法の底) を表します。これは既定値が 10 ではないので注意してください。

MDN Web Docs

基数ってナニ…って思ったんですが、要は進数のことらしいですね。

なので、第二引数が10なら10進数からの変換、8なら8進数…という具合になります。

10進数以外使ったことないけど。。他に使う機会あるのかな?

この第二引数を省略すると、事故ることがあるので指定するのが定石のようです。

toString – number 型から string 型への変換 –

こちらも引数には基数を指定します。

const number = 1;
const number2 = number.toString(10);
console.log(number2); // 1
console.log(typeof number2); // string

きちんと string 型に変換されましたね。

けど toString ってあまり使う機会がないな…parseInt の方がよく見かける印象。。(これは現場によるのかも)

詳しくはこちらよりどぞ↓

まとめ

今回は、number 型と string 型の違いでハマった話とその対処法について書いてみました。

なんとも初歩的なことで…という感じですが、知らないとドン詰まることがありますね…

単純にデバッグ時に変数の中身を見たときに「” “」で囲われていれば string 型だし、そうじゃなければ number 型ですよってことで。

JavaScript は色々とゆるゆるだなー。

ここまでお読みいただき、ありがとうございました!