JavaScriptの動かないコード (中級編) nullが0以上0以下と認識されてしまう
以下のJavaScriptコードが意図した動作をしないのは,なぜですか。(制限時間1分)
やりたい事:
- ラジオボタンの中で,どれかボタンが選択されたかを検証する。
- 何も選択されていない場合,警告のメッセージを表示。
<body> どれか選択して下さい。<br> <input type="radio" name="hoge" value="0"> 0 <br> <input type="radio" name="hoge" value="1"> 1 <br> <input type="radio" name="hoge" value="2"> 2 <br> <input type="radio" name="hoge" value="3"> 3 <br> <input type="button" value="値を検証" onclick="validate_value()"> <script language="JavaScript"> // ラジオが選択されたかどうかを検証する function validate_value(){ // 値を取得する var val = get_radio_value(); // 有効な値か? if( val >= 0 ) { // OKの場合 alert( "有効な値が選択されています。(値=" + val + ")" ); } else { // NGの場合 alert( "ラジオが未選択です。値を選択してください。" ); } } // ラジオボタンで選択されている数値を返します。 // もし,何も選択されていない場合,nullを返します。 function get_radio_value() { var val = null; // name属性によってradioの要素を全部取得 var radio_elems = document.getElementsByName("hoge"); // チェックされている物の値を保存 for( var i = 0; i < radio_elems.length; i ++ ) { if( radio_elems[ i ].checked ) { // 数値に変換しておく val = parseInt( radio_elems[ i ].value, 10 ); } } return val; } </script> </body>
答え
発生する不具合
IEでもFirefoxでも,ラジオが未選択の場合
「有効な値が選択されています。(値=null)」
と表示されてしまう。
( val >= 0 ) の所で,nullが有効な値として通過してしまっている。
理由
なんと・・・以下の式が成立する。
- null >= 0 である。
- null <= 0 である。
数値比較の際nullは,0以上・0以下とみなされる。
しかも
- null != 0 である。
0以上,0以下だが,0ではないのだ。
数学的にはありえないが,JavaScriptではこれが仕様である。
null と 0 の比較CommentsAdd Star
http://d.hatena.ne.jp/higeorange/2008...
抽象的関係比較アルゴリズム (The Abstract Relational Comparison Algorithm) によると null が +0 になる
ECMAスクリプト仕様書:型変換
http://www2u.biglobe.ne.jp/~oz-07ams/...
nullを数値に変換すると+0になる
単なる0ではなく,内部値「+0」として扱われる,というのがまたややこしい。
JavaScriptで「+0」と書いても「0」と同じとみなされるが,そうではなくてJavaScriptの処理系自体が内部で「+0」という数学値を仮想的に持っているという事だ。
下記の式が成り立つ。
- +0 <= 0 である。(したがってnull <= 0)
- +0 >= 0 である。(したがってnull >= 0)
さらに,大小の比較ではなく等価の比較の場合,nullの数値変換が行なわれない(ToNumber(x)ではなくType(x)により比較がなされる)ので,単純に
- null != 0
となる。