JavaScriptの値比較でハマった話

前置き

プログラマ転職して1年経ったけど、
SESで働いてて入社2日目からずっと現場勤務(同じ会社の人いない現場)、
9月末でコロナの影響で予算縮小、切られて10月から自社待機してる。
現場には1年1カ月勤務した。たくさんお世話になった人いるし、
すごく感謝してる。逆にいま自社の人と接点ないし毎日つらい。

そんな状況で時間を持て余してるので
いままで書いたコードのリファクタリングしたり
応用情報の勉強したりしてる。(応用情報は先日受験した)

なんとなくやりたくなって、Javaで書いたWebアプリを
Servlet+JSPからJSP廃止してServlet+HTML(JS,JQueryでデータ処理)に
修正するのにはまってる。

そして修正したアプリはPaaS(heroku)にデプロイして遊んでみる。

前置きが長くなったけど、JSP廃止してJavaScriptを使用したときに
ハマった内容を2点、下記にメモとして置いておく。

その1.String型のまま数値比較はダメ

はまったこと

すごく当たり前の話なのですが。
数値比較するときはString型だったらちゃんとNumber型に変換しないとダメ。
そんな当たり前のことで嵌まってしまったのが私です。
いままでJavaばっかり書いてきて、事前に型を決めてるから
値比較は何も考えずに下記のように書いてた。

// int型に文字列を格納しようとしてコンパイルエラー
// int num1 = "6";
// int num2 = "55";
  
// これが正しい
int num1 = 6;  
int num2 = 55;  

boolean result = false;

if(num2 > num1){
    result = true;
}
// resultはtrueになる

で、JavaScriptで何も考えず書いた間違った値比較が下記。

var num1 = "6";
var num2 = "55";

var result = false;

if(num2 > num1){
    result = true;
}
// resultはfalseになる 正しくない!!

理由は下記の記事参考
javascript 文字列のまま数字を比較すると危険が危ない。 - かもメモ

実際にはvar num1やnum2にはJavaからJSONでデータ渡してます。
そもそもJava側で数値型の状態("1"じゃなく1)で渡せって話なんですが、
Jacksonライブラリ使ってMapにして面倒だったので全部Stringで渡してしまいました。
調べればInt型で送る手段あるのでしょうがそこまで手をつけず。

解決策

値比較する前に文字列型→数値型に変換する

var num1 = Number("6"); // 数値型に変換
var num2 = Number("55"); // 数値型に変換

var result = false;

if(num2 > num1){
    result = true;
}
// resultはtrueになる  

その2.なんでもかんでも明示的に型変換すればよいわけでもない?

はまったこと

その1を解決して私は思いました。
「値比較する前には、明示的に型変換してあげるのがきっと正しい!」

そして書いたのが下記。

var bool = Boolean("false"); // Boolean型に変換?  
  
var result = false;

// boolがfalseなのだからresultがtrueになるはずない・・・
if(bool == true){
    result = true;
}

// resultはtrueになる 正しくない!!

boolにfalseを入れたはず、と思ってたのが、
なぜかBoolean("false") → trueに。

調べてみるとBoolean()での値変換は
上記の場合trueになるのが仕様らしい。
JavaScript難しい・・・

解決策

下記の記事を参考にした。
javascript で string 型と boolean 型を相互に変換 – II

var bool = "false";
  
var result = false;

if(bool == "true"){
    result = true;
}

// resultはfalseになる

つまりはそのまま何も考えずに文字列のまま使った。
JavaScript難しい・・・