【问题标题】:Converting an int64 value to a Number object in JavaScript在 JavaScript 中将 int64 值转换为 Number 对象
【发布时间】:2010-05-05 17:15:43
【问题描述】:

我有一个 COM 对象,它有一个返回无符号 int64 (VT_UI8) 值的方法。我们有一个 HTML 页面,其中包含一些 JavaScript,它可以加载 COM 对象并调用该方法,以检索值:

var foo = MyCOMObject.GetInt64Value();

这个值可以很容易地在消息对话框中显示给用户,使用:

alert(foo);

或通过以下方式显示在页面上:

document.getElementById('displayToUser').innerHTML = foo;

但是,我们不能将此值用作数字(例如,如果我们尝试将其乘以 2)而不会使页面抛出“预期数字”错误。如果我们检查“typeof(foo)”,它会返回“unknown”。

我通过执行以下操作找到了解决方法:

document.getElementById('displayToUser').innerHTML = foo;
var bar = parseInt(document.getElementById('displayToUser').innerHTML);
alert(bar*2);

我需要知道的是如何让这个过程更有效率。具体来说,有没有一种方法可以将 foo 显式转换为 String,而不必将某些文档元素的 innerHTML 设置为 foo 然后从中检索它。我不介意这样称呼:

alert(parseInt((string)foo) * 2);

如果有一种方法可以直接将 int64 转换为数字,而不经过字符串转换,那就更好了,但我对此抱有较小的希望。

【问题讨论】:

  • Javascript 中的所有数字都是双精度数。因此,您应该注意,将 64 位 int 转换为双精度可能会降低一些精度。

标签: javascript com type-conversion int64


【解决方案1】:

这个:

alert(Number(String(foo)) * 2);

应该这样做(但见下文),如果您的 COM 对象正确实现 toString(或带有“字符串”提示的 valueOf)(显然它确实如此,如果您的 @987654324 @ 技巧有效——因为当您将foo 分配给innerHTML 时,将发生与String(foo) 相同的将COM 对象转换为字符串的过程。

来自第 5 版 ECMAScript 规范的第 15.5.1 节:

当 String 作为函数而不是构造函数调用时,它会执行类型转换。

以及第 15.7.1 节

当 Number 作为函数而不是构造函数调用时,它会执行类型转换

可能值得尝试Number(foo) * 2 来确保,但我认为它不会起作用(看起来你的 COM 对象只处理转换为字符串,而不是数字,这并不奇怪或不合理) .


编辑如果 String(foo) 失败,请尝试:

alert(Number("" + foo) * 2);

非常惊讶于您的 innerHTML 技巧有效,但 String(foo) 抛出错误。希望"" + foo 将触发与您的innerHTML 技巧相同的隐式 转换。


编辑 好吧,这个 COM 对象确实很奇怪。我接下来的两次齐射:

alert(("" + foo) * 2);

这使用所有隐式转换(将对象添加到字符串会将对象转换为字符串;将* 运算符应用于字符串会将其转换为数字)。

或者,我们可以使字符串->数字转换显式但间接:

alert(parseInt("" + foo) * 2);

【讨论】:

  • 我试过了,不幸的是,调用“String(foo)”会产生“String expected”错误。
  • @Matt:改用alert(Number("" + foo) * 2)。 (我非常String(foo) 不起作用感到惊讶,但如果innerHTML = foo 起作用,那么"" + foo 应该起作用。)(编辑我的答案以包括这个。)
  • 有趣,结果显然总是 0,所以这也行不通。不过还是谢谢。
  • @Matt:你试过alert(parseInt("" + foo) * 2)吗?以防万一? (或者,实际上,alert(("" + foo) * 2) 应该可以工作——这是使用所有隐式转换。)(答案已编辑;也许它应该只是一个选项列表,对那些不起作用的选项使用删除线。:-))
  • @TJ 不幸的是,这些也没有用。它们都导致“NaN”。不过,感谢您的所有帮助!
【解决方案2】:

呃。好吧,如果由于宿主对象的奇怪行为而没有任何显式转换起作用,那么让我们试试隐式转换:

var n= +(''+foo);

我假设您不介意目标类型 Number 不涵盖 int64 的全部值范围(它是 double,因此您只能得到 52 位尾数)。

【讨论】:

  • 这导致 n 被设置为 0。我知道 Number 不会给我我需要的范围,但总比什么都没有好(特别是因为我从未见过这个特定的方法返回结果不适合 32 位)。
【解决方案3】:

马特,从 cmets 到其他答案,我怀疑您是在某种循环中运行此代码。如果是这样,请确保在尝试转换之前检查返回的值是否为 null。

var foo = MyCOMObject.GetInt64Value(); 
if (foo == null) {
  foo = 0; // Or something else
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    • 2019-05-26
    • 1970-01-01
    • 2022-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多