在JavaScript中将String转换为Number的最快方法是什么?


122

任何数字,就是数字。字符串看起来像一个数字,它是数字。其他所有内容都将继续保留。

'a' => NaN
'1' => 1
1 => 1

最快的时间取决于给定时间的给定实现中的优化。没有客观的“最快”方法。
我讨厌懒惰的2012年

2
'1a'字符串应该怎么做?与' 1'一个?换句话说,为什么最常用的方法不足以做到这一点(Number(x)parseInt(x, 10))?
raina77ow 2012年


这里是不同方法的良好性能比较:jsben.ch
#

Answers:


191

据我所知,有4种方法可以做到这一点。

Number(x);
parseInt(x, 10);
parseFloat(x);
+x;

通过我所做的快速测试,它实际上取决于浏览器。

http://jsperf.com/best-of-string-to-number-conversion/2

Implicit 在3个浏览器上标记为最快,但是它使代码难以阅读...因此,请选择任何您喜欢的方式!


7
有趣的是,Google Analytics(您粘贴到您网站中的部分)1*用于日期到数字的转换,与+上面的类似。即1*new Date()不是+new Date()。可能更具可读性吗?
Matthew Wilcoxson

1
我认为1*它是首选,因为它不容易出错。之前不需要的悬挂变量+1不是解析错误。这是类似于使用技巧if (MYCONSTANT == myvar)C
托马斯

5
@beatak-当前的优化似乎偏向于本机方法,而不是隐式转换。我在Windows Server 2008 R2 / 7上的Chrome 37.0.2062.124和Firefox 30.0中的ParseInt()的Number()最快,而隐式是两者中最慢的。另外,您可以考虑在测试中包括字符串文字浮点数,以进行一般比较。我的猜测是,在某些情况下它可能会更改顺序,因为从字符串到浮点的转换通常比从字符串到int的转换要慢。现在的测试方式是,在使用Number()时,不再需要将字符串转换为int了。
2014年

1
铬61.0.3163。Number()是最快的。
德米特里·佩图霍夫

70

至少有5种方法可以执行此操作:

如果只想转换为整数,则另一种快速(简短)的方法不是按位方式转换(即使用两个波浪号字符):

例如

~~x;

参考:http : //james.padolsey.com/cool-stuff/double-bitwise-not/

到目前为止,我所知道的将字符串转换为数字的5种常见方式都有其差异(存在更多按位运算符,但它们的结果与相同~~)。此JSFiddle显示了您在调试控制台中可以预期的不同结果:http : //jsfiddle.net/TrueBlueAussie/j7x0q0e3/22/

var values = ["123",
          undefined,
          "not a number",
          "123.45",
          "1234 error",
          "2147483648",
          "4999999999"
          ];

for (var i = 0; i < values.length; i++){
    var x = values[i];

    console.log(x);
    console.log(" Number(x) = " + Number(x));
    console.log(" parseInt(x, 10) = " + parseInt(x, 10));
    console.log(" parseFloat(x) = " + parseFloat(x));
    console.log(" +x = " + +x);
    console.log(" ~~x = " + ~~x);
}

调试控制台:

123
  Number(x) = 123
  parseInt(x, 10) = 123
  parseFloat(x) = 123
  +x = 123
  ~~x = 123
undefined
  Number(x) = NaN
  parseInt(x, 10) = NaN
  parseFloat(x) = NaN
  +x = NaN
  ~~x = 0
null
  Number(x) = 0
  parseInt(x, 10) = NaN
  parseFloat(x) = NaN
  +x = 0
  ~~x = 0
"not a number"
  Number(x) = NaN
  parseInt(x, 10) = NaN
  parseFloat(x) = NaN
  +x = NaN
  ~~x = 0
123.45
  Number(x) = 123.45
  parseInt(x, 10) = 123
  parseFloat(x) = 123.45
  +x = 123.45
  ~~x = 123
1234 error
  Number(x) = NaN
  parseInt(x, 10) = 1234
  parseFloat(x) = 1234
  +x = NaN
  ~~x = 0
2147483648
  Number(x) = 2147483648
  parseInt(x, 10) = 2147483648
  parseFloat(x) = 2147483648
  +x = 2147483648
  ~~x = -2147483648
4999999999
  Number(x) = 4999999999
  parseInt(x, 10) = 4999999999
  parseFloat(x) = 4999999999
  +x = 4999999999
  ~~x = 705032703

~~x版本在“更多”的情况下会产生一个数字,而其他情况通常会导致undefined,但由于无效输入而导致失败(例如,0如果字符串有效数字之后包含非数字字符,它将返回)。

溢出

请注意:,可能会发生整数溢出和/或位截断~~,但其他转换则不会。虽然输入这么大的值并不常见,但是您需要意识到这一点。示例已更新为包含更大的值。

一些Perf测试表明标准parseIntparseFloat功能实际上是最快的选项,可能是浏览器对其进行了高度优化,但这取决于您的要求,因为所有选项都足够快http : //jsperf.com/best-of-string-to -number-conversion / 37

这一切都取决于性能测试的配置方式,因为一些show parseInt / parseFloat要慢得多。

我的理论是:

  • 谎言
  • 织补线
  • 统计
  • JSPerf结果:)

3
请务必小心大于2147483647的数字,例如: ~~4294967296return 0
约瑟夫·格(Joseph Goh),

@JosephGoh:如果有机会,我将扩展结果以包括int范围溢出。通常,如果数量如此之大,则您将有一个非常特殊的接口,因此需要注意溢出。干杯
编码

@JosephGoh:有趣的是,在Chrome中,您没有得到0,得到的负数超过了有符号的最大值。然后,当您超过unsigned int max值时,似乎只是丢弃了多余的位。例如“ 4999999999” => 705032703
编码

8

+运算符前缀字符串。

console.log(+'a') // NaN
console.log(+'1') // 1
console.log(+1) // 1

7

将字符串转换为整数的快速方法是使用按位或,如下所示:

x | 0

尽管它取决于实现方式,+x但从理论上讲,它应该相对较快(至少与一样快),因为它将首先x转换为数字,然后执行非常有效的or。


是的,但是我相信这种技术会截断大整数,这非常糟糕。需要注意的是,我也可以代替Math.floor()使用,但存在相同的问题。
让(Jean)

是各种按位运算符jsperf以及第一个答案中的方法。我将顺序随机化,因为我发现某些浏览器会根据前一个测试的相似代码来优化下一个测试。与最高回答者不同,我发现隐式是最糟糕的方法。
冥王星

4

这是简单的方法: var num = Number(str); 在此示例中,str是包含字符串的变量。您可以对其进行测试并查看其工作方式:Google chrome开发人员工具,然后转到控制台并粘贴以下代码。阅读评论以更好地了解转换是如何完成的。

// Here Im creating my variable as a string
var str = "258";


// here im printing the string variable: str
console.log ( str );


// here Im using typeof , this tells me that the variable str is the type: string
console.log ("The variable str is type: " + typeof str);


// here is where the conversion happens
// Number will take the string in the parentesis and transform it to a variable num as type: number
var num = Number(str);
console.log ("The variable num is type: " + typeof num);


3

这可能没有那么快,但是具有确保您的数字至少是某个值(例如0)或最多是某个值的附加好处:

Math.max(input, 0);

如果您需要确保最小值,通常会

var number = Number(input);
if (number < 0) number = 0;

Math.max(..., 0) 使您不必编写两个语句。


为什么不使用Math.abs(input)?它还将字符串转换为正数,并节省一些额外的字符。
亚伦·吉利安

1
@AaronGillion:Math.max(-5,0)将返回0; Math.abs(-5)将返回5。这取决于更有意义的用例。
Dan Dascalescu 2016年

1
哦,哎呀,是的,无论我写了什么深夜,我的用例都大相径庭。
亚伦·吉利恩

如果input不能转换为数字,则将获得NaN
Domas Mar

0

您可以尝试使用UnitOf,这是我们刚刚正式发布的测量和数据类型转换库!UnitOf超级快,体积小并且可以高效地转换任何数据类型,而不会抛出错误或null / undefined。转换不成功时,将返回您定义的默认值或UnitOf的默认值。

//One liner examples
UnitOf.DataType("12.5").toFloat(); //12.5 of type Float is returned. 0 would be returned if conversion failed.
UnitOf.DataType("Not A Num").toInt(10); //10 of type Int is returned as the conversion failed.

//Or as a variable
var unit = UnitOf.DataType("12.5");
unit.toInt(5); //12.5 of type Float is returned. 5 would be returned if the conversion failed.
unit.toFloat(8); // 12 of type Int is returned. 8 would be returned if the conversion failed.

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.