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難しい・・・