公開日: 2009年08月04日(Tue)
JavaScriptを実装していて、文字列を数値にキャストする parseInt()
はよく使う。結構よく考えずに数値にしたいときにサクっと使っちゃうんだけど、今日はうっかりこいつのワナにはまったので、メモしとく。(ほんとはワナじゃないんだけど・・・)
気をつけなきゃいけないのは、渡した文字列が 0 から始まってた場合。
0 から始まる数字は8進数を表す(ちなみに 0x から始まると16進数)。だから、「010」のような文字列を渡した場合に、parseInt()
は引数を8進数と判断してしまうのだ。
alert(010);//「8」と出る。
alert(parseInt('010'));//「8」と出る。
alert(0x10);//「16」と出る。
alert(parseInt('0x10'));//「16」と出る。
こんなのも8進数として計算されるようだ。
alert(0010);//「8」と出る。
alert(parseInt('0010'));//「8」と出る。
よくよく考えればその通りの動きなんだけど、注意しないと見落としそう(特にPHPの intval() に慣れてると・・・)。気をつけよう。
対象が確実に文字列とわかってるなら、次のように無理やり先頭の 0 を削除して通せば、見た目通りの数値が得られる。
alert( '010'.replace(new RegExp('^0+'),'') );//「10」と出る。
そして、大変残念なことに、Operaだけこの挙動が異なるようだ。(ガッデム!)
alert(010);//「8」と出る。
alert(parseInt('010'));//Operaだけ「10」と出る。
parseInt()
に 文字列 "010" を渡したときに、見た目通り 10 と判断するようだ。
ちなみに、Operaも16進数は他のブラウザと同じ動きをした。
alert(0x10);//「16」と出る。
alert(parseInt('0x10'));//「16」と出る。
このテストを実施してみたのは、Firefox 3, Netscape 9, Safari 3.2, Chrome 2.0, Opera 9.64, IE6, IE7。簡単だけど、テストに使ったHTMLも一応添付しときます。
追記: 2013-07-21
新しいブラウザでテストしたところ、8進数の処理が変わっているようです。
alert(parseInt('010'));//「10」と出る。
テストしたブラウザは下記。
IEも、バージョン9から挙動が変わっているみたい。仕様が変わったんですかね?
ちなみに、16進数の処理は変わっていませんでした。
alert(parseInt('0x10'));//「16」と出る。
公開日: 2009年08月04日(Tue)