ホームページとは一見、文章とデザインで構成されるもののように見られがちです。
ですが最近のホームページは「システム」の要素が強く、いたるところにプログラミング要素が含まれています。
特に、ブラウザ側だけで動作するJavascriptは手軽であるため、本当によく使います。
最近では、Javascriptがまったく使われていないホームページ自体が珍しいのではないでしょうか。
今回も多分に漏れずJavascriptで「計算」をして結果を表示する処理を作っていたのですが、その際に「あれっ?」となる部分がありました。
Javascriptならではの現象だったのですが、思いのほかはまったので、忘備録として記録いたします。
今回の問題現象
Javascriptで足し算をすると答えがおかしくなりました。
<script>
var a = "3";
var b = "2";
var ans = a + b;
console.log(ans);
</script>
上記の処理をやってみたところ、答えは「32」と表示されました。
3+2なので5になるはずがなぜ32?
と頭をひねっていたら、原因はすぐわかりました。
原因は「文字結合」
Javascriptには文字結合というものがあります。
文字と文字を結合する処理です。
<script>
var a = "今日は";
var b = "良い天気";
var comment = a + b;
console.log(comment);
</script>
上記を実行すると「今日は良い天気」と表示されます。
つまり、Jasascriptで文字を足し算すると文字結合になるのです。
文字「3」と文字「2」を結合したから「32」となっていました。
事実、以下のように記述すると答えは「5」になりました。
<script>
var a = 3;
var b = 2;
var ans = a + b;
console.log(ans);
</script>
初めから数字として設定すれば文字結合にならず、数字として計算されました。
これで解決!
と思いましたが、問題はそんな簡単ではありませんでした。
フォームから投稿された数字は文字として取得される
今回作ろうとしていたのは、フォームから数字を入力し計算するというものです。
ところが、フォームから入力された数字は文字として渡されます。
文字を足し算すると文字結合となり、数字の足し算としては誤った答えになります。
これを何とかできないか調べました。
Javascriptでもキャストができます
今回の現象がPHPであればキャストで対処します。
詳細は割愛しますが、文字であっても数字として認識させる記述をします。
しかしJavascriptで以下のような記述をしたら文法エラーになりました。
<script>
var a = "3";
var b = "2";
var ans = (int)a + (int)b;
// ↑のような記述は文法エラー
console.log(ans);
</script>
PHPならば、上記のような記述でキャストできますが、Javascriptだと文法エラーです。
着眼点はよいと思ったのですが言語の壁がありました。
なのでググって調べると、Javascriptのキャストの方法は次のようなものでした。
<script>
var a = "3";
var b = "2";
var ans = Number(a) + Number(b);
// Javascriptでは文字数字をNumber()関数で囲う
console.log(ans);
</script>
他の言語と違う独特なキャスト記述でした。
ただ、このやり方をすると答えは「5」と期待していた値になりました。
この現象の難しいところは足し算だけおかしくなる点
Javascript文字を足し算すると文字結合になることはわかるのですが、今回の現象のむつかしい点は、足し算以外であれば、文字数字はそれなりに計算されるという点です。
<script>
var a = "3";
var b = "2";
var ans1 = a * b;
var ans2 = a / b;
var ans3 = a - b;
</script>
- ans1の答えは「6」
- ans2の答えは「1.5」
- ans3の答えは「1」
文字であっても、足し算以外の計算はそれなりに実行されます。
足し算だけ文字結合になるためややこしかったです。
言語の微妙な違いを知ることも大事
プログラミング言語は一つマスターすると、他の言語は習得しやすくなります。
なぜならば、記述方法がほとんど同じだからです。
例えばif文であったりとか、関数の記述であったりとか、言語が違っても記述方法がほとんど同じなため、あまり気にせず記述ができます。
ただ細かい部分で記述が異なる部分があり、今回はそこに悩まされました。
Javascriptは他の言語に比べると異なる部分が多いため、落とし穴にはまりやすかったりします。
(実際よくはまります)
今回のような経験をとおして、Javascriptの特性を改めて知ることができました。