node.js parseInt 与一元加 - 何时使用哪个
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17106681/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
parseInt vs unary plus - when to use which
提问by hereandnow78
What are the differences between this line:
这行有什么区别:
var a = parseInt("1", 10); // a === 1
and this line
和这条线
var a = +"1"; // a === 1
This jsperf testshows that the unary operator is much faster in the current chrome version, assuming it is for node.js!?
这个jsperf 测试表明一元运算符在当前的 chrome 版本中要快得多,假设它是用于 node.js!?
If I try to convert strings which are not numbers both return NaN:
如果我尝试转换不是数字的字符串都返回NaN:
var b = parseInt("test" 10); // b === NaN
var b = +"test"; // b === NaN
So when should I prefer using parseIntover the unary plus (especially in node.js)???
那么我什么时候应该更喜欢使用parseInt一元加号(尤其是在 node.js 中)???
edit: and what's the difference to the double tilde operator ~~?
编辑:与双波浪号运算符有~~什么区别?
回答by georg
The ultimate whatever-to-number conversion table:

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 }
回答by Joseph
Please see this answerfor a more complete set of cases
请参阅此答案以获取更完整的案例集
Well, here are a few differences I know of:
好吧,这是我所知道的一些差异:
An empty string
""evaluates to a0, whileparseIntevaluates it toNaN. IMO, a blank string should be aNaN.+'' === 0; //true isNaN(parseInt('',10)); //trueThe unary
+acts more likeparseFloatsince it also accepts decimals.parseInton the other hand stops parsing when it sees a non-numerical character, like the period that is intended to be a decimal point..+'2.3' === 2.3; //true parseInt('2.3',10) === 2; //trueparseIntandparseFloatparses and builds the string left to right. If they see an invalid character, it returns what has been parsed (if any) as a number, andNaNif none was parsed as a number.The unary
+on the other hand will returnNaNif the entire string is non-convertible to a number.parseInt('2a',10) === 2; //true parseFloat('2a') === 2; //true isNan(+'2a'); //trueAs seen in the comment of @Alex K.,
parseIntandparseFloatwill parse by character. This means hex and exponent notations will fail since thexandeare treated as non-numerical components (at least on base10).The unary
+will convert them properly though.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.
空字符串
""计算为 a0,而将其parseInt计算为NaN。IMO,空白字符串应该是NaN.+'' === 0; //true isNaN(parseInt('',10)); //true一元的
+行为更像,parseFloat因为它也接受小数。parseInt另一方面,当它看到一个非数字字符时停止解析,比如打算作为小数点的句点.。+'2.3' === 2.3; //true parseInt('2.3',10) === 2; //trueparseInt并从左到右parseFloat解析和构建字符串。如果他们看到无效字符,它将返回已解析的内容(如果有)作为数字,如果没有被解析为数字。NaN+另一方面,NaN如果整个字符串不可转换为数字,则一元将返回。parseInt('2a',10) === 2; //true parseFloat('2a') === 2; //true isNan(+'2a'); //true正如看到的评论@Alex K.,
parseInt并parseFloat会性格解析。这意味着十六进制和指数符号将失败,因为x和e被视为非数字组件(至少在 base10 上)。一元
+会正确地转换它们。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.
回答by djechlin
The table in thg435's answer I believe is comprehensive, however we can summarize with the following patterns:
我认为 thg435 的答案中的表格很全面,但是我们可以总结为以下模式:
- Unary plus does not treat all falsy values the same, but they all come out falsy.
- Unary plus sends
trueto 1, but"true"toNaN. - On the other hand,
parseIntis more liberal for strings that are not pure digits.parseInt('123abc') === 123, whereas+reportsNaN. Numberwill accept valid decimal numbers, whereasparseIntmerely drops everything past the decimal. ThusparseIntmimics C behavior, but is perhaps not ideal for evaluating user input.- Both trim whitespace in strings.
parseInt, being a badly designed parser, accepts octal and hexadecimal input. Unary plus only takes hexademical.
- 一元加号不会将所有的假值都一视同仁,但它们都会出现假值。
- 一元加号发送
true到 1,但发送"true"到NaN。 - 另一方面,
parseInt对于非纯数字的字符串则更为宽松。parseInt('123abc') === 123,而+报告NaN。 Number将接受有效的十进制数,而parseInt只会删除小数点之后的所有内容。因此parseInt模仿 C 的行为,但可能不适合评估用户输入。- 两者都修剪字符串中的空格。
parseInt,作为一个设计糟糕的解析器,接受八进制和十六进制输入。一元加只取十六进制。
Falsy values convert to Numberfollowing what would make sense in C: nulland falseare both zero. ""going to 0 doesn't quite follow this convention but makes enough sense to me.
Falsy 值转换为Number以下在 C: 中有意义的 值null,false并且都为零。 ""转到 0 并不完全遵循这个约定,但对我来说已经足够了。
Therefore I think if you are validating user input, unary plus has correct behavior for everything except it accepts decimals (but in my real life cases I'm more interested in catching email input instead of userId, value omitted entirely, etc.), whereas parseInt is too liberal.
因此,我认为如果您正在验证用户输入,除了接受小数之外,一元加号对所有内容都有正确的行为(但在我的现实生活中,我更感兴趣的是捕获电子邮件输入而不是 userId、完全省略值等),而parseInt 太自由了。
回答by Informate.it
Be carefull, parseInt is faster than + unary operator in Node.JS, it's false that + or |0 are faster, them are faster only for NaN elements.
注意,在 Node.JS 中 parseInt 比 + 一元运算符快,+ 或 |0 更快是错误的,它们仅对 NaN 元素更快。
Check this out:
看一下这个:
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));
回答by Arman McHitarian
Consider performancetoo. I was suprised that parseIntbeats unary plus on iOS :) This is helpful for web apps with heavy CPU consumption only. As a rule-of-thumb I'd suggest JS opt-guys to consider any JS operator over another one from the mobile performance point of view nowadays.
还要考虑性能。我很惊讶它parseInt在 iOS 上击败了一元加 :) 这仅对 CPU 消耗量很大的网络应用程序很有帮助。作为一个经验法则,我建议 JS 选择人员从当今的移动性能角度考虑任何 JS 运营商而不是另一个运营商。
So, go mobile-first;)
所以,移动优先;)

