【问题标题】:How to make sure parseInt() function does not return unexpected results如何确保 parseInt() 函数不会返回意外结果
【发布时间】:2015-08-10 02:46:46
【问题描述】:

以下是将毫秒转换为人类可读时间的方法。但是我收到了一条评论,说它可能会返回一些基数的意外结果。

function msToTime(duration, sign) {
  var milliseconds = parseInt((duration % 1000) / 100),
    seconds = parseInt((duration / 1000) % 60),
    minutes = parseInt((duration / (1000 * 60)) % 60),
    hours = parseInt((duration / (1000 * 60 * 60)) % 24);

  hours = (hours < 10) ? "0" + hours : hours;
  minutes = (minutes < 10) ? " " + minutes : minutes;
  seconds = (seconds < 10) ? "0" + seconds : seconds;

  return minutes + sign + seconds;
}

$("div").text(msToTime(1203400, ":"));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<div></div>

这是我收到的评论:“如果未提供基数,parseInt() 函数可能会返回不希望的和/或意外的结果。请确保在所有 parseInt() 实例上都使用基数。”

我尝试添加日、周、月、年等,但我不确定这是否正确。它也适用于一段音乐。所以我认为不会有任何情况超过几个小时。

有什么办法可以确保方法的结果始终正确吗?

【问题讨论】:

  • 也许您应该考虑到发表评论的人是错误的,因为您的代码表明 durration 已经是一个 int。如果我可以是一个字符串,比如一个十六进制数字,那么你的代码会以不同的方式被破坏
  • 上面的评论想说的是:你实际上想parseInt你的持续时间你开始用它执行计算。在你的例子中,事情会在那之前发生。

标签: javascript jquery function parseint


【解决方案1】:

parseInt() 将第二个参数称为 radix 作为其第二个参数

一个介于 2 到 36 之间的整数,表示基数(在 上述字符串的数学数字系统)。指定 10为人类常用的十进制数字系统。总是 指定此参数以消除读者混淆并保证 可预测的行为。不同的实现产生不同的 未指定基数时的结果。

由于你是在处理十进制数系统,所以将基数作为 10 来解决这样的问题

parseInt((duration % 1000) / 100, 10)

【讨论】:

  • 感谢您的回复。所以我应该为我在函数中使用的每个 parseInt 指定基数?
  • @DanJF 这取决于您的用例...我通常会指定它们
  • @DanJF - 关于parseInt() 的所有这些信息在技术上都是正确的,但事实证明,在OP 的函数中甚至不需要parseInt(),因为它们传递的是一个数字,而不是一个字符串。而且,即使他们传入一个字符串,您也必须使用parseInt(duration, 10),而不是parseInt((duration % 1000) / 100, 10)
【解决方案2】:

Radix 是 parseInt() 采用的第二个参数,它是一个数字(从 2 到 36),表示要使用的数字系统。您应该使用 10,因为它代表十进制数字系统。

var milliseconds = (parseInt(duration) % 1000) / 100, 10)

如果没有传递基数,将使用以下内容:

如果字符串以“0x”开头,则基数为 16(十六进制)。

如果字符串以“0”开头,则基数为 8(八进制)。这个功能是 已弃用

如果字符串以任何其他值开头,则基数为 10 (十进制)

如果你不总是想指定它,创建一个这样的函数:

function parseInt10(val){
    return parseInt(val,10);
}

【讨论】:

  • 一般来说,你想要 10,除非你喜欢尝试非标准的数字系统。
  • @XMLilley 你认为二进制、八进制和十六进制是非标准的吗?
  • @michael,您需要指出您的报价是针对未传递基数时的,例如如果你传递一个基数,parseInt('0x10', 8) 将给出0
  • 谢谢@PaulS.,我忘了。
  • @PaulS.,非标准?对于这个OP? (谁不知道基数是什么,谁的用例显然是十进制的?)对于那个用户来说,除了 base-10 之外的任何东西都是非常不标准的方法。 (就此而言,基于二进制、八进制和十六进制的计算可能是非常有用和必不可少的工具,但在绝大多数情况下,它们与绝大多数用户完全无关。人们首先需要学习的是如何做十进制。)
【解决方案3】:

其他答案是为您提供有关 parseInt() 的一些建议,这在技术上是正确的,但与您的实际代码无关,因为您甚至不需要在函数中使用 parseInt()

由于您似乎已经将一个数字(而不是字符串)传递给您的函数,您甚至不需要任何 parseInt() 操作,并且可以像这样简化它:

function msToTime(duration, sign) {
  var milliseconds = (duration % 1000) / 100,
    seconds = (duration / 1000) % 60,
    minutes = (duration / (1000 * 60)) % 60,
    hours = (duration / (1000 * 60 * 60)) % 24;

  hours = (hours < 10) ? "0" + hours : hours;
  minutes = (minutes < 10) ? " " + minutes : minutes;
  seconds = (seconds < 10) ? "0" + seconds : seconds;

  return minutes + sign + seconds;
}

如果您希望您的函数在持续时间内接受传入的数字或字符串,您可以这样支持:

function msToTime(t, sign) {
  var duration = +t;
  var milliseconds = (duration % 1000) / 100,
    seconds = (duration / 1000) % 60,
    minutes = (duration / (1000 * 60)) % 60,
    hours = (duration / (1000 * 60 * 60)) % 24;

  hours = (hours < 10) ? "0" + hours : hours;
  minutes = (minutes < 10) ? " " + minutes : minutes;
  seconds = (seconds < 10) ? "0" + seconds : seconds;

  return minutes + sign + seconds;
}

而且,如果您确实使用了parseInt(),您会将持续时间转换为数字:

var d = parseInt(duration, 10);

然后,在您的计算中使用该值。正如您的代码现在所拥有的那样,您正在对数学计算的结果调用parseInt(),这意味着您正在对一个没有任何作用的数字调用parseInt

【讨论】:

    猜你喜欢
    • 2011-05-19
    • 1970-01-01
    • 1970-01-01
    • 2011-12-02
    • 1970-01-01
    • 1970-01-01
    • 2021-10-06
    • 2017-11-14
    • 1970-01-01
    相关资源
    最近更新 更多