181

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

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

そしてこの行

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

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

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

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

parseIntでは、単項プラスよりも (特に node.js で)いつ使用することをお勧めしますか?

edit : 二重チルダ演算子との違いは何~~ですか?

4

6 に答える 6

337

究極の数値変換テーブル: 換算表

EXPRS = [
    'parseInt(x)',
    'parseFloat(x)',
    'Number(x)',
    '+x',
    '~~x',
    'x>>>0',
    'isNaN(x)'

];

VALUES = [
    '"123"',
    '"+123"',
    '"-123"',
    '"123.45"',
    '"-123.45"',
    '"12e5"',
    '"12e-5"',
    
    '"0123"',
    '"0000123"',
    '"0b111"',
    '"0o10"',
    '"0xBABE"',
    
    '"4294967295"',
    '"123456789012345678"',
    '"12e999"',

    '""',
    '"123foo"',
    '"123.45foo"',
    '"  123   "',
    '"foo"',
    '"12e"',
    '"0b567"',
    '"0o999"',
    '"0xFUZZ"',

    '"+0"',
    '"-0"',
    '"Infinity"',
    '"+Infinity"',
    '"-Infinity"',

    'null',
    'undefined',
    'true',
    'false',
    'Infinity',
    'NaN',

    '{}',
    '{valueOf: function(){return 42}}',
    '{toString: function(){return "56"}}',

];

//////

function wrap(tag, s) {
    if (s && s.join)
        s = s.join('');
    return '<' + tag + '>' + String(s) + '</' + tag + '>';
}

function table(head, rows) {
    return wrap('table', [
        wrap('thead', tr(head)),
        wrap('tbody', rows.map(tr))
    ]);
}

function tr(row) {
    return wrap('tr', row.map(function (s) {
        return wrap('td', s)
    }));
}

function val(n) {
    return n === true || Number.isNaN(n) ? wrap('b', n) : String(n);
}

var rows = VALUES.map(function (v) {
    var x = eval('(' + v + ')');
    return [v].concat(EXPRS.map(function (e) {
        return val(eval(e))
    }));
});

document.body.innerHTML = table(["x"].concat(EXPRS), rows);
table { border-collapse: collapse }
tr:nth-child(odd) { background: #fafafa }
td { border: 1px solid #e0e0e0; padding: 5px; font: 12px monospace }
td:not(:first-child) { text-align: right }
thead td { background: #3663AE; color: white }
b { color: red }

于 2013-06-14T10:46:34.823 に答える
199

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

  • 空の文字列""は に評価されますが、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.のコメントに見られるように、文字ごとparseIntparseFloat解析されます。これは、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.
    
于 2013-06-14T10:46:34.200 に答える
11

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

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

Falsy 値は、C で意味のある次のように変換されますNumber。 両方ともゼロです。 0 に行くということは、この慣例には完全に従っていませんが、私には十分に理にかなっています。nullfalse""

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

于 2013-06-27T17:39:42.643 に答える
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));
于 2015-03-11T18:43:06.070 に答える
-3

パフォーマンスも考慮してください。parseIntiOS で unary plus を上回っていることに驚きました:) これは、CPU の消費量が多い Web アプリにのみ役立ちます。経験則として、最近のモバイル パフォーマンスの観点から、JS を選択する人には、別の JS オペレーターよりも他の JS オペレーターを検討することをお勧めします。

だから、モバイルファーストに行きましょう;)

于 2013-07-19T14:08:04.260 に答える