Hatena::ブログ(Diary)

三等兵

うさぎともふもふしたりうさぎともっふもっふしたり。プログラミングしたり。

2010-02-06

通常の数値かどうかはisNaN関数じゃなくてisFinite関数

そういえばJSはブログでは久しぶりでした。

NaNでちょっとめんどうなことになったんですが、何かなーと思ったらNumberオブジェクト(のプロパティ:追記)だったのですね。

console.log(typeof(NaN)); // number

というわけでありがちなミスをしてしまいまして。数値以外ははじこうとしてこういうようなことをやってしまいました。これの前にparseIntで文字列から数値に変換し、それぞれ配列に入れたという設定。

var arr = [2, 4, 6, 12, 45, NaN, 47, 1322, NaN];
for(var i = 0; i < arr.length; i++) {
  if(typeof(arr) == 'number'){
    //
  }
}

だめですね。うん。NaNはNumberオブジェクト(のプロパティ:追記)だもの。じゃあ数値かどうかでやろうかなーと思って探したらisNaN関数というものがありました。それでやってたら、なんか思ってた結果を得られない。おかしいというわけで関数を個別に使いまして、

console.log(isNaN(1)); // false

false??なぜ?1って数値じゃんないですか?isNaNって数値かどうか判定するんじゃないの?おかしいのでしっかり見ました。


指定した値が数値かどうかを調べます。値が数値ならば false、数値でない場合は true を返します。

http://www.scollabo.com/banban/jsindex/sample/sample_116.html

数値だとfalseになるんですって。なんて直感的に使いづらい関数!数値判定でそりゃないでしょう何かの間違いだ。


isNaN - 数値かどうかを調べる

http://javascriptist.net/ref/isnan.html

し、信じないぞ!


ある値が数値かどうかというチェックはよくやりますね。

http://yakinikunotare.boo.jp/orebase/index.php?Javascript%2F%BF%F4%C3%CD%A4%C7%A4%A2%A4%EB%A4%AB%A4%CE%A5%C1%A5%A7%A5%C3%A5%AF

だ、だまされるもんか!


数値かどうか調べます。Netscape 4.0以外動作せずにエラーになります。数値であった場合false、文字の場合trueが返されます。Explorer 3.0xの場合は常に0を返します。

http://www.openspc2.org/JavaScript/ref/convert/isNaN.htm

ふ、ふん、そうやって私を陥れる気ですね…


数字 (または '') の場合 false, それ以外は true を返す。

http://keicode.com/jsref/global.isnan.php

ほ、ほほう。な、なかなか、インターネッツも、手の込んだ悪さをするもんですなぁ。大人をなめるもんじゃありませんよ。


与えられた値が数値かどうかを調べるビルトイン関数。

もし値が数値の場合は「false」を,数値でない場合は「true」を返す。

Netscape3.X以前のUNIX版以外のブラウザでは,機能しない場合がある。

http://itpro.nikkeibp.co.jp/article/Reference/20081126/319919/

ITPro、お前もか。お前が言うなら信じるしか…


isNaN 関数は引数を評価し、その引数が "NaN"(not a number; 非数)であるかどうかを決定します。isNaN の構文は次のとおりです。

https://developer.mozilla.org/ja/Core_JavaScript_1.5_Guide/Predefined_Functions/isNaN_Function

ですよねー!いやー私はそうじゃないかと確信していたんで疑いもしませんでしたがねッ。悪の組織がね。googleとかいう悪の組織の陰謀がね。isNaNの正体を隠そうとね。


してないけどもね。


納得。だから数値だったらfalseなのですね。ただしundefinedでもtrueになったりしました。

console.log(isNaN(undefined)) // true
console.log(isNaN('1aaa')) // true
console.log(isNaN([54, 12])) // true
console.log(isNaN({hoho : 12})) // true

これ全部数値に変換するとNaNになるのか。微妙に使いづらい。他に何か良いのないかということで、isFinite関数がありました。

引数が NaN、正の無限大、または負の無限大である場合、このメソッドは false を返し、そうでない場合は true を返します。

https://developer.mozilla.org/ja/Core_JavaScript_1.5_Guide/Predefined_Functions/isFinite_Function

いろいろ試してみました。

console.log(isFinite(NaN)); // false
console.log(isFinite(undefined)) // false
console.log(isFinite('1aaa')) // false
console.log(isFinite([54, 12])) // false
console.log(isFinite({hoho : 12})) // false
console.log(isFinite(Infinity)); // false

大丈夫ですね。通常の数値かどうかを判断するんだったらisFinite関数の方が良さそう。ちなみに真理値の場合、

console.log(isFinite(true)); // true
console.log(isFinite(false)) // true

1と0になるのでこうなります。


あと文字列から数値に変換する方法だけど、私はparseInt()が良いけど関数使うと少し遅いのでしょうか。別に大規模なことやらないから多少遅かろうがどうでもかまわないのだけれど、気になったのでこちらのを使ってやってみました。ちょっと変えてます。

http://d.hatena.ne.jp/mindcat/20090906/1252242178

function perf(x) {
  var i = '1';
  while (x-- > 0) {
   i = ; //ここにそれぞれの数値変換の処理
  }
}

function test() {
  var n = 5000000;
  var tm1 = (new Date).getTime();
  perf(n);
  var tm2 = (new Date).getTime();
  alert("tm=" + (tm2 - tm1));
}

Firefox3.0のみなのでいろいろ古いし比較していないけども。まあ過去はこんなもんだったのよーという具合で。

i = +x; // 225
i = Number(x); // 6274
i = parseInt(x); // 811
i = parseFloat(x); // 3924
i = eval(x); // 7374

いつのときも(+)を使うのが一番みたい。

katsunojikatsunoji 2010/04/20 09:23 isNaNが何の略か知ってれば結構直感的ですよ。
ただ空文字("")でもFalseを返すのは微妙…

sandaisandai 2010/04/22 23:21 コメントありがとうございます。空文字はisFiniteでも一緒ですね。
NaNについてはそのとき知らなかったので、
数値かどうかなのになんでfalseなんだと混乱しました。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証