web-dev-qa-db-ja.com

JavaScriptのparseInt 8進数の動作を回避するにはどうすればよいですか?

JavaScriptで次を実行してみてください。

parseInt('01'); //equals 1
parseInt('02'); //equals 2
parseInt('03'); //equals 3
parseInt('04'); //equals 4
parseInt('05'); //equals 5
parseInt('06'); //equals 6
parseInt('07'); //equals 7
parseInt('08'); //equals 0 !!
parseInt('09'); //equals 0 !!

JavaScriptが先行ゼロが 8進整数 を示すと考える難しい方法を学びましたが、base-8には"8"または"9"がないため、関数はゼロを返します。好むと好まざるとにかかわらず、 これは仕様による

回避策は何ですか?

注:完全を期すために、私は解決策を投稿しようとしていますが、それは私が嫌いな解決策なので、他の/より良い答えを投稿してください。


更新:

JavaScript標準の第5版( ECMA-262 )は、この動作を排除する重大な変更を導入しています。 Mozillaには優れた write-up があります。

278
Portman

これは、簡単な解決策を備えた一般的なJavascriptの落とし穴です。

ベースを指定 、または 'radix'のように:

parseInt('08',10); // 8

Number を使用することもできます。

Number('08'); // 8
323

knowの値が符号付き32ビット整数の範囲にある場合、~~xはすべてのシナリオで正しいことを行います。

~~"08" === 8
~~"foobar" === 0
~~(1.99) === 1
~~(-1.99)  === -1

バイナリではなく(~)を検索する場合、Int32への明らかな変換を行い、NaN値をゼロに強制するように指定された引数の「ToInt32」変換が仕様に必要です。

はい、これは信じられないほどハックですが、とても便利です...

42
Karl Guertin

parseInt documentation から、オプションの基数引数を使用してbase-10を指定します。

parseInt('08', 10); //equals 8
parseInt('09', 10); //equals 9

これは、つまらなく、混乱し、冗長である(実際、すべてのparseIntに余分な引数があります)ので、私はより良い方法があることを望んでいます。

24
Portman
function parseDecimal(s) { return parseInt(s, 10); }

編集:あなたが本当にしたいことをするために独自の関数を作ることは、parseInt()呼び出しに常に "、10"を追加したくない場合の単なるオプションです。非標準関数であるという欠点があります。頻繁に使用する方が便利ですが、他の人にとっては混乱を招く可能性があります。

11
Jason S

ベースを指定します。

var number = parseInt(s, 10);
10
RichieHindle

ParseIntを2番目のパラメーターがない場合に10進数を想定したバージョンに置き換えるのは非常に面倒ですか? (注-未テスト)

parseIntImpl = parseInt
parseInt = function(str, base){return parseIntImpl(str, base ? base : 10)}
7
Andrew Duffy

ParseFloatまたはparseIntを使用する代わりに、単項演算子(+)を使用することもできます。

+"01"
// => 1

+"02"
// => 2

+"03"
// => 3

+"04"
// => 4

+"05"
// => 5

+"06"
// => 6

+"07"
// => 7

+"08"
// => 8

+"09"
// => 9

そして良い対策のために

+"09.09"
// => 9.09

MDNリンク

単項プラス演算子は、オペランドの前に置かれ、オペランドに評価されますが、まだオペランドになっていない場合は、数値に変換しようとします。単項否定(-)も非数値を変換できますが、単項プラスは、何かを数値に変換する最も高速で推奨される方法です番号に対して他の操作を実行します。

5
SoEzPz

10進数の場合はどうですか:

('09'-0) === 9  // true

('009'-0) === 9 // true
5
Gordon K

ParseIntで既に多くのコーディングを行っており、すべてに "、10"を追加したくない場合は、関数をオーバーライドしてベース10をデフォルトにすることができます。

window._oldParseInt = window.parseInt;
window.parseInt = function(str, rad) {
    if (! rad) {
        return _oldParseInt(str, 10);
    }
    return _oldParseInt(str, rad);
};

それは後の読者を混乱させるかもしれないので、parseInt10()関数を作ることはもっと自明かもしれません。個人的には、常に "、10"を追加するよりも単純な関数を使用することを好みます-間違いの機会を増やすだけです。

4