【JavaScript】 parseInt() で 8進数のワナに気をつけろ!

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」と出る。

テストしたブラウザは下記。

Mac × Chrome 28.0.1500.71
10 と出る。
Mac × Firefox 22.0
10 と出る。
Mac × Opera 10.8.4
8 と出る。
Win × IE 6〜8
8 と出る。
Win × IE 9, 10
10 と出る。

IEも、バージョン9から挙動が変わっているみたい。仕様が変わったんですかね?

ちなみに、16進数の処理は変わっていませんでした。

alert(parseInt('0x10'));//「16」と出る。

プロフィール

コヤナギ トモヤ

まったりウェブ系コーダーしてます。PHP製静的CMS Pickles 2 を開発しています。

RSSフィード

  • このサイトは、 コヤナギ トモヤ の個人サイトです。
  • 個人的な主張や、活動の記録などを掲載しています。 所属する企業、団体、その他の意見や立場を代表するものではありません。
  • 掲載された内容は古くなっている可能性があります。 特に古い記事では、現在の筆者の考えと異なる主張をしていることがありますが、記録としてそのまま残しております。 予めご了承ください。
ページの先頭へ戻る