parseInt vs単項プラス、どちらを使用するのですか?


149

この行の違いは何ですか:

var a = parseInt("1", 10); // a === 1

そしてこの線

var a = +"1"; // a === 1

このjsperfテストは、現在のChromeバージョンでは、node.js用であると想定して、単項演算子の方がはるかに高速であることを示しています!?

数字ではない文字列を変換しようとすると、両方が返されNaNます:

var b = parseInt("test" 10); // b === NaN
var b = +"test"; // b === NaN

だから、私parseIntは単項プラスよりも(特にnode.jsで)使用することを好むべきですか???

編集:そして、二重チルド演算子との違いは何~~ですか?


回答:


169

ケースのより完全なセットについては、この回答を参照しください




さて、ここに私が知っているいくつかの違いがあります:

  • 空の文字列はに""評価されますが0、にparseInt評価されNaNます。IMO、空の文字列はである必要がありNaNます。

    +'' === 0;              //true
    isNaN(parseInt('',10)); //true
  • 単項は小数も受け入れるので、+より機能parseFloatします。

    parseInt一方、小数点のように意図されているピリオドのように、数値以外の文字が検出されると、解析が停止します.

    +'2.3' === 2.3;           //true
    parseInt('2.3',10) === 2; //true
  • parseIntそしてparseFloat、文字列を解析して左から右に構築します。無効な文字が表示された場合は、解析されたもの(ある場合)が数値として返され、数値として解析されたものがない場合は返されますNaN

    +一方、単項は、NaN文字列全体が数値に変換できない場合に返されます。

    parseInt('2a',10) === 2; //true
    parseFloat('2a') === 2;  //true
    isNan(+'2a');            //true
  • コメントで見@Alex K.parseIntおよびparseFloat文字で解析します。これは、xeが非数値コンポーネントとして扱われるため(少なくともbase10では)、16進数と指数表記は失敗します。

    単項+はそれらを適切に変換します。

    parseInt('2e3',10) === 2;  //true. This is supposed to be 2000
    +'2e3' === 2000;           //true. This one's correct.
    
    parseInt("0xf", 10) === 0; //true. This is supposed to be 15
    +'0xf' === 15;             //true. This one's correct.

6
また、基数を使用する場合+"0xf" != parseInt("0xf", 10)
Alex K.

私はこれまでのところあなたの答えが好きです。また、二重チルド演算子~~との違いを説明できますか?
hereandnow78 2013年

@ hereandnow78 ここ説明します。これはMath.floor()、ビット単位でと同等であり、基本的に小数部を切り捨てます。
ジョセフ

4
実際、"2e3"はの有効な整数表現ではありません2000。ただし、これは有効な浮動小数点数です。答えとしてparseFloat("2e3")正しく生成さ2000れます。そして、"0xf"理由は少なくともベース16、必要とparseInt("0xf", 10)戻り0、一方、parseInt("0xf", 16)リターン15の値は、あなたが期待していたが。
バート

2
@ジョセフ・ザ・ドリーマーと@ hereandnow78:Math.floorが最も近い小さい数値を返すのに対し、ダブルチルダは数値の小数部分を切り捨てます。正の数でも同じように機能しますがMath.floor(-3.5) == -4、および~~-3.5 == -3です。
アルビン

261

究極の何から数への変換表でも: 換算表


2
"NaN"この表に追加してください。
chharvey、2014

isNaNこのテーブルに列を追加する価値があるかもしれません。たとえば、isNaN("")false(つまり、数値と見なされます)parseFloat("")ですがNaN、これはisNaN、入力に渡す前に入力を検証するために使用しようとすると、問題になる可能性がありますparseFloat
Retsam

また'{valueOf: function(){return 42}, toString: function(){return "56"}}'、リストに追加する必要があります。混合結果は興味深いものです。
murrayju

3
それで、表の要約は、それ+は単に書くのNumberに短い方法であり、さらに遠くのものは、エッジケースで失敗する、それを行うためのクレイジーな方法です?
Mihail Malostanidis

[] .undefは何かですか、それとも未定義を生成する任意の方法ですか?Google経由でJSに関連する「undef」のレコードが見つかりません。
jcairney

10

thg435の回答の表は包括的だと思いますが、次のパターンで要約できます。

  • 単項プラスはすべての偽の値を同じように扱うわけではありませんが、それらはすべて偽って出てきます。
  • 単項プラスtrueは1に送信しますが、に送信"true"NaNます。
  • 一方、parseInt純粋な数字ではない文字列の場合はより自由です。 parseInt('123abc') === 123一方で、+報告NaN
  • Number有効な10進数を受け入れますが、10進数をparseInt超えてすべてを削除します。したがってparseInt、Cの動作を模倣しますが、ユーザー入力の評価にはおそらく理想的ではありません。
  • どちらも文字列内の空白を削除します。
  • parseIntは、不適切に設計されたパーサーであり、8進数および16進数の入力を受け入れます。単項プラスは16進数のみを使用します。

Falsy値はに変換Number:Cで意味をなすだろうか、次の nullfalse両方ゼロです。 ""0にすることはこの規則には完全には従いませんが、私には十分な意味があります。

したがって、ユーザー入力を検証している場合、単項プラスは小数を受け入れる以外はすべて正しく動作すると思います(ただし、実際のケースでは、userIdではなく電子メール入力をキャッチしたり、値を完全に省略したりするなど)。 parseIntは自由すぎる。


2
「単項プラスは16進数のみを取る」10進数を意味するのではないですか?
krillgar

0

注意してください。parseIntはNode.JSの単項演算子よりも高速です。+または| 0の方が高速であるというのは誤りです。これらはNaN要素に対してのみ高速です。

これをチェックしてください:

var arg=process.argv[2];

rpt=20000;
mrc=1000;

a=[];
b=1024*1024*1024*1024;
for (var i=0;i<rpt;i++)
 a[i]=Math.floor(Math.random()*b)+' ';

t0=Date.now();
if ((arg==1)||(arg===undefined))
 for (var j=0;j<mrc;j++) for (var i=0;i<rpt;i++) {
  c=a[i]-0;
 }
t1=Date.now();
if ((arg==2)||(arg===undefined)) {
 for (var j=0;j<mrc;j++) for (var i=0;i<rpt;i++) {
  d=a[i]|0;
 }
}
t2=Date.now();
if ((arg==3)||(arg===undefined)) {
 for (var j=0;j<mrc;j++) for (var i=0;i<rpt;i++) {
  e=parseInt(a[i]);
 }
}
t3=Date.now();
 if ((arg==3)||(arg===undefined)) {
 for (var j=0;j<mrc;j++) for (var i=0;i<rpt;i++) {
  f=+a[i];
 }
}
t4=Date.now();

console.log(a[i-1],c,d,e,f);
console.log('Eseguiti: '+rpt*mrc+' cicli');
console.log('parseInt '+(t3-t2));
console.log('|0 '+(t2-t1));
console.log('-0 '+(t1-t0));
console.log('+ '+(t4-t3));

-3

パフォーマンスも考慮してください。parseIntiOSで単項プラスに勝るとは驚きました:)これは、CPUの消費量が多いWebアプリにのみ役立ちます。経験則として、今日のモバイルパフォーマンスの観点から、JSオプトギィに他のJSオペレーターを検討することをお勧めします。

だから、モバイル第一に ;)


他の投稿で説明されているように、それらの動作はまったく異なるため、一方を他方と簡単に交換することはできません…
Bergi

@Bergi、そうですが、共通点もたくさんあります。間違いなく唯一正しい選択であるJavaScriptのパフォーマンスソリューションを1つだけ教えてください。一般的に、それが私たちの経験則がそこにある理由です。残りはタスク固有です。
Arman McHitarian 2013

3
@ArmanMcHitaryanこれは役に立たないマイクロ最適化であり、価値はありません。この記事をチェックアウト- fabien.potencier.org/article/8/...を
webvitaly

@webvitaly、素晴らしい記事。「可能な限り最速の」コードを書きたいと思っているパフォーマンス重視の人は常にいますし、特定のプロジェクトでは悪くないです。それが私が「考慮すべきJSオプトガイ」と述べた理由です。もちろんこれは必須ではありません:)が、私自身はさらに読みやすくなっています。
Arman McHitarian 2013

これについての引用はありますか?リンクが壊れています。
djechlin
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.