Конвертировать число JavaScript n в строку s так, чтобы Object.is (eval (s), n) для всех n? - PullRequest
0 голосов
/ 06 июля 2018

Мне нужно преобразовать произвольные числа JavaScript в строки, содержащие выражения JavaScript, которые гарантированно будут иметь то же значение, что и исходное число.

Как правило, String() подходит для большинства значений, но, в частности, String(-0) возвращает '0', и хотя 0 === -0, Object.is(0, -0) возвращает false.

Существуют ли другие числовые значения n, для которых eval(String(n)) не возвращает значение n? Я имею в виду, в частности, случаи, когда число с плавающей запятой не может быть точно выражено в десятичном виде, и представление String() выбирает оценки для ближайшего, но другого числа с плавающей запятой из-за округления / недостаточной точности.

Если так, как я могу получить eval -значное строковое представление этих чисел?

Ответы [ 2 ]

0 голосов
/ 07 июля 2018

-0 является единственным исключением. Цитировать спецификацию (ПРИМЕЧАНИЕ 1):

Если x - это любое числовое значение, отличное от -0, то ToNumber (ToString (x)) будет точно таким же числовым значением, что и x.

Обратите внимание, что поведение String(x) заключается в простом вызове ToString(x), когда x отличается от символа ( spec ).

Никакая точность никогда не теряется при преобразовании числа в строку. Может быть в другом формате, чем оригинал, но всегда будет представлять одно и то же число:

console.log( String(1e2) );
console.log( Object.is(1e2,100) );

Как уже упоминалось @ASDFGerte, Infinity и NaN могут быть затенены. Поэтому вы можете также добавить исключения для Infinity, -Infinity и NaN. Может быть что-то вроде:

function reversibleNumberToString( x ) {
  if ( Object.is( -0, x ) )
    return '-0';
  const str = String(x);
  switch ( str ) {
    case 'Infinity':
      return '1/0';
    case '-Infinity':
      return '-1/0';
    case 'NaN':
      return '0/0';
    default:
      return str;
  }
}

// Tests
[ 0, 1, Math.random( ), -Infinity, Infinity, NaN ].forEach( x => {
  const Infinity = 'shadowed';
  console.log( Object.is( x, eval( reversibleNumberToString( x ) ) ) );
} );
0 голосов
/ 06 июля 2018

с функцией Номер

например:

Number('0') === 0 // true
...