【问题标题】:Fastest way to check if a JS variable starts with a number检查 JS 变量是否以数字开头的最快方法
【发布时间】:2013-01-22 21:09:12
【问题描述】:

我将一个对象用作哈希表,并将常规属性和整数作为键填充到其中。

我现在有兴趣计算这个对象中的键的数量,这些键是数字,但显然 for (x in obj) { if (typeof x === "number") { ... } } 不会产生我想要的结果,因为所有键都是字符串。

因此,我确定如果键的第一个字符是数字,那么它必须是数字就足够了,因此我不担心键“3a”是否“错误地”确定为数字。

鉴于这种放松,我想​​我可以像这样检查它

for (x in obj) {
  var charCode = x.charCodeAt(0);
  if (charCode < 58 && charCode > 47) { // ascii digits check
     ...
  }
}

从而避免使用正则表达式和parseInt 等。

这行得通吗? charCodeAt 是 JS 1.2,所以这应该是防弹的,是吗?

提示:我希望看到一个 jsperf 将我的函数与每个人提出的函数进行比较。 :) 我会自己做,但 jsperf 让我很困惑

更新:感谢您启动 JSPerf,它证实了我希望 charCodeAt 函数将执行一段非常快速的代码来读取字符的 int 值。其他方法涉及解析。

【问题讨论】:

  • 我觉得不错。 1.2 早在 1997 年就发布了,所以除非你的目标是 Internet Explorer 3.0,否则你会很安全。
  • @Ofear 看来您试图提供不正确的建议。请阅读我的第二段
  • 你也需要考虑负整数吗?如果是这样,您还有一个标志可以允许...
  • @ScottSauyet,我做了一个:jsperf.com/is-string-a-number - 随意分叉和编辑。

标签: javascript


【解决方案1】:

parseInt(x, 10) 将正确解析字符串中的前导正数或负数,所以试试这个:

function startsWithNumber(x) {
    return !isNaN(parseInt(x, 10));
}

startsWithNumber('123abc'); // true
startsWithNumber('-123abc'); // true
startsWithNumber('123'); // true
startsWithNumber('-123'); // true
startsWithNumber(123); // true
startsWithNumber(-123); // true
startsWithNumber('abc'); // false
startsWithNumber('-abc'); // false
startsWithNumber('abc123'); // false
startsWithNumber('-abc123'); // false

【讨论】:

    【解决方案2】:

    you can measure 时为什么要猜测。在 Chrome 上,您的方法似乎是最快的。在我的测试运行中,提议的替代方案都落后了大约 60%。

    【讨论】:

    • 谢谢!在 JSPerf 上很少看到 60M ops/s
    • 哇!看看 Firefox 18 的那个栏!!有些东西告诉我 JIT 正在优化某些东西。
    • @StevenLu,是的,我也必须自己测试,得到了非常相似的结果。我会看看我是否可以更改测试用例,这样 JIT 就不会因为冗余而删除代码路径,我认为这是正在发生的事情。
    • @StevenLu 在回答这个问题后,我们在 Chrome 中获得了 65M 次代码,在 Firefox 中获得了 450M 次代码:stackoverflow.com/questions/14218363/…。
    • @StevenLu 要么我不知道如何欺骗firefox js 编译器,要么firefox 在charCodeAt 上真的那么快:jsperf.com/is-string-a-number/4
    【解决方案3】:

    这个问题具有误导性,因为很难说出 变量 的名称,但在示例中,您正在处理对象属性(当然是某种变量... )。在这种情况下,如果您只需要知道它是否以数字开头,那么最好的选择可能是parseInt。对于任何不以数字开头的字符串,它将返回NaN。

    【讨论】:

    • 确实,parseInt 也是一个不错的选择,并且在性能上可能与 isNaN 相似,但很明显只需要检查第一个字符。
    【解决方案4】:

    您也可以使用isNaN(x) 或isFinite(x) - 请参阅this SO question

    【讨论】:

    • 所以问题是,是否比 ( 47) 检查更好/更快
    • 我会认为它更好,因为如果稍后您添加密钥“123foo”,它不会中断
    • 这与原始解决方案有不同的答案,尽管可能更好。 !isNan('3a') === false,而originalSolution('3a') === true。
    猜你喜欢
    • 2011-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-04
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    相关资源
    最近更新 更多