【问题标题】:What's the fastest way to convert String to Number in JavaScript?在 JavaScript 中将字符串转换为数字的最快方法是什么?
【发布时间】:2012-10-12 15:43:07
【问题描述】:

任何数字,它都是数字。字符串看起来像一个数字,它是数字。其他的都是 NaN。

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

【问题讨论】:

标签: javascript


【解决方案1】:

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

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

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

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

Implicit 在 3 个浏览器上标记为最快,但它使代码难以阅读……所以选择你喜欢的任何东西!

【讨论】:

  • 有趣的是,Google Analytics(您粘贴到您网站的部分)使用1* 进行日期到数字的转换,这类似于上面的+。即1*new Date() 而不是+new Date()。可能它更具可读性?
  • 我认为1* 是首选,因为它不易出错。 +1 之前不需要的悬空变量不是解析错误。这是一个类似于在C 中使用if (MYCONSTANT == myvar) 的技巧。
  • @beatak - 当前的优化似乎有利于本机方法,而不是隐式转换。我在 Windows Server 2008 R2 / 7 上的 Chrome 37.0.2062.124 中的 Number() 和 Firefox 30.0 中的 ParseInt() 中速度最快,其中隐式是最慢的。此外,您可能会考虑在测试中包含字符串文字浮点数以进行一般比较。我的猜测是在某些情况下它可能会改变顺序,因为字符串到浮点数的转换通常比字符串到 int 的转换慢。现在的测试方式是,当使用 Number() 时,它会使用字符串到 int 的转换。
  • Chrome 61.0.3163。 Number() 是最快的。
  • 我刚刚比较了Number()~~(在jsben.ch 上运行了几次),Number() 赢了,尽管有时几乎是平的。
【解决方案2】:

至少有 5 种方法可以做到这一点:

如果您只想转换为整数,另一种快速(且简短)的方法是 double-bitwise not(即使用两个波浪号):

例如

~~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 em>在一个有效数字之后)。

溢出

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

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

这完全取决于性能测试的配置方式,因为某些显示 parseInt/parseFloat 的速度要慢得多。

我的理论是:

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

【讨论】:

  • 对于大于 2147483647 的数字要非常小心。例如:~~4294967296 返回0
  • @JosephGoh:当我有机会时,我会扩展结果以包括 int 范围溢出。一般来说,如果数字很大,那么您有一个非常特殊的界面正在进行,因此需要注意溢出。干杯
  • @JosephGoh:有趣的是,在 Chrome 中,您不会得到 0,而是会得到超过有符号最大值的负数。然后,当您超过 unsigned int 最大值时,它似乎只是删除了额外的位。例如"4999999999" => 705032703
【解决方案3】:

使用+ 运算符为字符串添加前缀。

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

【讨论】:

    【解决方案4】:

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

    x | 0
    

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

    【讨论】:

    • 是的,但我相信这种技术会截断大整数,这很糟糕。需要注意的是,我也可以用来代替 Math.floor(),但有同样的问题。
    • 这是jsperf of various bitwise operators 与第一个答案中的方法一起使用。我将顺序随机化,因为我发现一些浏览器会根据上一个测试中的类似代码优化下一个测试。与最佳回答者不同,我发现隐式是最糟糕的方法。
    【解决方案5】:

    这是一个简单的方法: var num = Number(str); 在这个例子中 str 是包含字符串的变量。 你可以打开测试看看它是如何工作的:谷歌浏览器开发者工具,然后进入控制台并粘贴以下代码。 阅读 cmets 以更好地了解转换是如何完成的。

    // 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);
    

    【讨论】:

      【解决方案6】:

      我发现num * 1 简单明了,适用于整数和浮点数...

      【讨论】:

        【解决方案7】:

        这可能不是那么快,但有一个额外的好处是确保你的数字至少是一个特定的值(例如 0),或者最多是一个特定的值:

        Math.max(input, 0);
        

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

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

        Math.max(..., 0) 让你不用写两个语句。

        【讨论】:

        • 为什么不使用Math.abs(input)?它还将字符串转换为正数,并节省了一些额外的字符。
        • @AaronGillion:Math.max(-5, 0) 将返回 0; Math.abs(-5) 将返回 5。这取决于更有意义的用例。
        • 哦,哎呀,是的,在我写该评论的深夜,我的用例完全不同。
        • 如果input不能转换成数字,你会得到NaN
        【解决方案8】:

        您可以尝试使用我们刚刚正式发布的度量和数据类型转换库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.
        

        【讨论】:

          【解决方案9】:

          最快的方法是使用-0:

          const num = "12.34" - 0;
          

          【讨论】:

            猜你喜欢
            • 2011-08-11
            • 1970-01-01
            • 2021-06-25
            • 2020-10-24
            • 1970-01-01
            相关资源
            最近更新 更多