Преобразование значения int64 в объект Number в JavaScript - PullRequest
0 голосов
/ 05 мая 2010

У меня есть 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 в число, не проходя преобразование String, но у меня меньше надежд начто.

Ответы [ 3 ]

3 голосов
/ 05 мая 2010

Это:

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

должен это сделать (но см. Ниже ), если ваш COM-объект реализует toString (или valueOf с подсказкой "string") правильно (и, очевидно, это так, если ваш innerHTML хитрость работает - потому что когда вы присваиваете foo для innerHTML, происходит тот же процесс преобразования COM-объекта в строку, что и для String(foo)).

Из раздела 15.5.1 спецификации ECMAScript 5-го издания:

Когда String вызывается как функция, а не как конструктор, он выполняет преобразование типа.

А, раздел 15.7.1

Когда Number вызывается как функция, а не как конструктор, он выполняет преобразование типа

Возможно, стоит попробовать просто Number(foo) * 2, чтобы убедиться, но я не думаю, что это сработает (кажется, что ваш COM-объект обрабатывает только преобразование в String, а не Number, что не удивительно или неразумно) .


Редактировать Если String(foo) не удается, попробуйте:

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

Я очень удивлен, что ваш innerHTML трюк работает, но String(foo) выдает ошибку. Надеемся, что "" + foo вызовет такое же неявное преобразование, как ваш innerHTML трюк.


Редактировать Хорошо, этот COM-объект действительно очень странный. Мои следующие два залпа:

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

При этом используются все неявные преобразования (добавление объекта в строку преобразует объект в строку; применение оператора * к строке преобразует его в число).

Альтернативно, мы можем сделать преобразование строки-> числа явным, но косвенным:

alert(parseInt("" + foo) * 2);
1 голос
/ 05 мая 2010

Ик. Хорошо, если ни одно из явных преобразований не работает из-за странного поведения хост-объекта, давайте попробуем неявные:

var n= +(''+foo);

Полагаю, вы не возражаете, что целевой тип Number не охватывает весь диапазон значений int64 (это double, поэтому вы получите только 52 бита мантиссы).

0 голосов
/ 05 мая 2010

Мэтт, от комментариев к другим ответам, я подозреваю, что вы запускаете этот код в каком-то цикле. Если это так, убедитесь, что вы проверили возвращаемое значение на null, прежде чем пытаться преобразовать.

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