BLOGTIMES
2006/07/31

JavaScriptの型変換にはまる

  javascript 
このエントリーをはてなブックマークに追加

先日仕事でどうしてもJavaScriptをコーディングしないといけないという場面があったんですが、そこで見事にはまってしまいました。やりたかったのは2つの変数を算術的に比較したかったのですが、どうしてもそのような結果が得られませんでした。

"11" <= "3" は true ?

端的なコードとしては以下のような感じ。

<script type="text/javascript"><!-- var a = "11"; var b = "3"; if( a <= b ){ document.write("true"); } else { document.write("false"); } //--></script>

上記のプログラムのifの条件節は"11" <= "3"となるため、条件節が成り立たず、画面上には「false」が表示されるように一見思われるわけですが、実際に実行してみると表示されるのは「true」なのです。実際に適当なHTMLファイルに貼り付けてブラウザで表示させてみるとそれがウソではないことが分かります。

結論から言うと上記のプログラムは冒頭の変数の定義の部分を下記のようにすることで期待通りの操作をするようになります。

var a = 11; var b = 3;

プログラミングに詳しい人ならばピンと来ると思いますが、3と"3"はプログラミングにおいて前者は数値リテラルであり、後者は文字列リテラルとなるため、表記の違いは微々たる物ですがその解釈がぜんぜん違うのです

最近、僕の中でスタンダードになりつつあるPHPでは<=のオペランドは数値型のみなので、勝手に型変換が行われるためあまり不具合がなかったんですが、JavaScriptでは<=のオペランドは数値もしくは文字列となっているようです。そのため、文字列同士の比較が行われた結果、条件節が「true」と解釈されてしまったようです。原理が分かればどうって事はないんですが、こんなくだらないとが分かるまで30分もかかってしまいました。

JavaScriptでの型変換(文字列→数値)

今回の実際のプログラミングでは変数の値はある変数の戻り値だったので、文字列をどうにかして数値にしてやらないといけません。ということで色々調べた結果、JavaScriptで文字列を数値に変換する方法としては下記の2つがあるようです。

parseInt("String")を使う

組み込み関数であるparseInt()を使う方法。どっちかっていうとこちらが正統派な感じなんですが、Stringの部分について先頭から数値として解釈できる部分を数値リテラルとして解釈してくれます。そのため、先頭に00xがついている文字列を渡したりすると、8進数や16進数として解釈が行われ、逆に思わぬ動作になる可能性があるみたいです。

String -0を使う

こちらは-のオペランドが数値でないといけないことを利用して、処理系に自動的に型変換をさせようとするテクニックですね。表記がちょっとダサくて可読性が悪い感じがしますが、上記のように基数が10以外に解釈されることがないのでそのようなはまりも少ないみたいです。

なんかどっちもどっちですね。。。。。。。

思った通りではなく、書いたとおりに動く。それがプログラミング。

JavaScript

よくバグを戒めるために「プログラムは思った通りではなく、書いたとおりに動く」といわれたりしますが、正にその通りですね。ちゃんと言語仕様のリファレンスも読まずに付け焼刃的なことをやってはいけないです。ということで、本格的にJavaScriptの勉強をしようと決心したのでした。


    トラックバックについて
    Trackback URL:
    お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
    このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/1529
    Trackbacks
    ちょっと簡略化してあるが、JavaScriptで以下のコードがうまく動かなかった。for文の中にさえ入ってこない。 var kanto = &quot;8-14&quot;; var range = kanto.split(&quot;-&quot;); for (var i = range[0]; i &lt;= range[1]; i++) { // 処理 } 結局range[0]、range[1]をpar
    コードつれづれ (2012/03/24 13:01)
    Comments
    愛のあるツッコミをお気軽にどうぞ。[policy]
    古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
    Andy (2006/07/31 12:41) <%HatenaAuth()%>

    ぜひ,JavaScriptマスターになってください。

    hsur (2006/07/31 19:29) <%HatenaAuth()%>

    これでNP_Trackbackとかちょっとでもパワーアップさせられるといいんですけど。。。。。

    Comments Form

    コメントは承認後の表示となります。
    OpenIDでログインすると、即時に公開されます。

    OpenID を使ってログインすることができます。

    Identity URL: Yahoo! JAPAN IDでログイン