Какой лучший способ преобразовать число в строку в JavaScript?

519

Каков «лучший» способ преобразования числа в строку (с точки зрения скорости, чистоты, памяти и т. Д.)?

Некоторые примеры:

  1. String(n)

  2. n.toString()

  3. ""+n

  4. n+""

Pacerier
источник

Ответы:

516

нравится:

var foo = 45;
var bar = '' + foo;

На самом деле, хотя я обычно делаю это так для простого удобства, более 1000 итераций, как представляется, для грубой скорости есть преимущество для.toString()

Смотрите тесты производительности здесь (не мной, но нашел, когда я пошел писать свой собственный): http://jsben.ch/#/ghQYR

Самый быстрый на основе теста JSPerf выше: str = num.toString();

Следует отметить, что разница в скорости не слишком значительна, если учесть, что она может выполнить преобразование любым способом 1 миллион раз за 0,1 секунды .

Обновление: скорость, кажется, сильно отличается от браузера. В Chrome, num + ''кажется, быстрее всего на основе этого теста http://jsben.ch/#/ghQYR

Обновление 2: опять же, основываясь на моем тесте выше, следует отметить, что Firefox 20.0.1 работает .toString()примерно в 100 раз медленнее, чем '' + numобразец.

scunliffe
источник
58
Есть случаи, когда преобразование может не вернуть предпочтительный ответ: '' + 123e-50возврат "1.23e-48".
hongymagic
21
@hongymagic: этот ответ на самом деле является единственно возможным: число не заботится и не знает, как оно было введено, а стандартное печатное представление содержит ровно одну цифру перед точкой.
Сванте
4
Я запускал тест в jsben.ch/ghQYR , каждый раз, когда он показывает мне другой результат!
Марьям
2
Мне нравится этот ответ, потому null fooчто не выдает ошибку.
ttugates
2
@MaryamSaeidi: использование теста jsperf.com от drublic кажется более последовательным.
Хиральди
364

По моему мнению, n.toString()приз за его ясность, и я не думаю, что это несет какие-либо дополнительные издержки.

CarlosZ
источник
Это несет некоторые накладные расходы, хотя это незначительно в последних версиях браузера. По крайней мере, в Firefox Quantum
peterchaula
11
Это небезопасно. n может быть нулевым или неопределенным.
david.pfx
20
@ david.pfx вопрос спрашивает, как преобразовать числовые значения в строку. Предоставление примеров нечисловых значений (например null, undefined), которые не работают с этим ответом, вряд ли делает его «небезопасным».
Майкл Мартин-Smucker
5
@ MichaelMartin-Smucker: Если вы пишете много JS, вы понимаете, что вещи так редко режутся и сушатся. Вопрос был открытым, и хороший ответ IMO должен по крайней мере признать проблему строки, которая на самом деле является нулевой или неопределенной. YMMV.
david.pfx
@ david.pfx Я написал МНОГО js, и я не помню, когда в последний раз мне нужно было число в виде строки, и ничего, кроме числа в виде строки, было бы достаточно. Это правильный ответ. Нет ответа на вопрос об обработке nullили undefinedкак это зависит от конкретного приложения, хотя я представляю (n || defaultNumber).toString() , что большинство людей хотели бы в такой ситуации, я категорически не согласен, мы должны работать над всеми вопросами. Речь шла о преобразовании чисел в строки, хорошей архитектуре и других преобразованиях типов, где это необходимо, это отдельные уроки.
Джордж Райт
73

Явные преобразования очень понятны для тех, кто плохо знаком с языком. Использование принуждения типов, как предлагали другие, приводит к неоднозначности, если разработчик не осведомлен о правилах принуждения. В конечном счете, время разработки обходится дороже, чем процессорного времени, поэтому я бы оптимизировал для первого за счет последнего. Тем не менее, в этом случае разница, вероятно, незначительна, но если нет, я уверен, что есть несколько достойных JavaScript-компрессоров, которые оптимизируют подобные вещи.

Итак, по вышеуказанным причинам я бы пошел с: n.toString()или String(n). String(n)Вероятно, это лучший выбор, потому что он не потерпит неудачу, если nравен нулю или не определен.

Брайан Кайл
источник
12
Речь шла о преобразовании чисел, а не о преобразовании чисел, или null, или undefined. Если nэто nullили undefinedиз-за ошибки в моей программе, то я бы предпочел, чтобы моя программа не работала в этом состоянии, чтобы дать мне больше шансов найти и исправить ошибку. Сбои программы - это подарки для программиста, чтобы помочь ей найти ошибки :-). Альтернативой является поставка программного обеспечения, которое не работает, как задумано, тщательно скрывая ошибки. Итак, я не фанат использования String(n)для маскировки ошибки.
Мэтт Уоллис
1
String(n)подходит для использования в функциональном стиле, например, с комбайном подчеркивания _.compose(funcThatNeedsAStringParam, String).
Рик Мартинс
2
String (null) не приведет к сбою программы, но вернет буквальную строку «null», что, вероятно, не то, что вам нужно. Если данные могут на законных основаниях быть нулевыми, то вам нужно обрабатывать их явно.
Питер Смарт
1
@ MattWallis Я думаю, что это должно быть решение разработчика, а не ответчик, не так ли?
Форрестхопкинса
31

... Синтаксический анализатор JavaScript пытается проанализировать точечную запись числа как литерал с плавающей точкой.

2..toString(); // the second point is correctly recognized
2 .toString(); // note the space left to the dot
(2).toString(); // 2 is evaluated first

Источник

Мухаммед Ариф
источник
17

Язык в щеке очевидно:

var harshNum = 108;
"".split.call(harshNum,"").join("");

Или в ES6 вы можете просто использовать строки шаблона :

var harshNum = 108;
`${harshNum}`;
cssimsek
источник
Если я запускаю тесты с шаблонами ES6, иногда это даже оказывается быстрее, чем '' + numberметод. Тем не менее, результаты этих тестов сильно различаются при их многократном выполнении, поэтому не уверен, следует ли принимать их слишком серьезно.
Нико Ван Белль
15

Другие ответы уже охватывали другие варианты, но я предпочитаю этот:

s = `${n}`

Короткий, лаконичный, уже используемый во многих других местах (если вы используете современную платформу / версию ES), так что это безопасная ставка, любой программист поймет это.

Не то, чтобы это (обычно) имело большое значение, но оно также оказалось одним из самых быстрых по сравнению с другими методами .

johndodo
источник
Также безопасно, если n может быть не числом.
david.pfx
Но так ли это n.toString(), не так ли?
атп
1
@amn , если nэто undefinedбудет бросать синтаксическую ошибку, используя.toString()
Jee Мок
Разве это не дает тот же результат, что и String(n)во всех случаях? Разница лишь в том, что это менее понятно.
Беннет
И намного медленнее.
Адриан Варфоломей
12

Самый простой способ преобразовать любую переменную в строку - добавить пустую строку в эту переменную.

5.41 + ''    // Result: the string '5.41'
Math.PI + '' // Result: the string '3.141592653589793'
sgokhales
источник
2
Обратите внимание, что это должно быть внутри паренов: (5.41 + '')использовать методы String, такие как .substring()и другие
Gjaa
Почему это нужно отметить?
Адриан Варфоломей
7

Если вам нужно отформатировать результат в определенном количестве десятичных знаков, например, для представления валюты, вам нужно что-то вроде toFixed()метода.

number.toFixed( [digits] )

digits количество цифр, отображаемых после запятой.

Тим
источник
2
Небезопасно, если вы не знаете, что это число.
david.pfx
6

Я использовал https://jsperf.com для создания тестового примера для следующих случаев:

number + ''
`${number}`
String(number)
number.toString()

https://jsperf.com/number-string-conversion-speed-comparison

По состоянию на 24 июля 2018 года результаты говорят о том, что number + ''он самый быстрый в Chrome, в Firefox, который связан с литералами шаблонных строк.

И то String(number), и другое number.toString()на 95% медленнее, чем самый быстрый вариант.

тесты производительности, описание выше

Erick
источник
2

Мне нравятся первые два, так как их легче читать. Я имею тенденцию использовать, String(n)но это - только вопрос стиля чем что-либо еще.

Это если у вас нет строки как

var n = 5;
console.log ("the number is: " + n);

что самоочевидно

Aleadam
источник
2

Я думаю, что это зависит от ситуации, но в любом случае вы можете использовать .toString()метод, так как он очень понятен.

Serghei
источник
2

.toString () - это встроенная функция приведения типов, я не разбираюсь в этих деталях, но всякий раз, когда мы сравниваем встроенные методы приведения типов к явным методам, всегда предпочтительнее встроенные обходные пути.

Мубин Хан
источник
1

Если бы мне пришлось принять все во внимание, я предложу следующее

var myint = 1;
var mystring = myint + '';
/*or int to string*/
myint = myint + ''

ИМХО, это самый быстрый способ преобразования в строку. Поправь меня, если я ошибаюсь.

Кумар
источник
1

Единственное допустимое решение для почти всех возможных существующих и будущих случаев (входные данные - число, ноль, неопределенное значение, символ и все остальное) String(x). Не используйте 3 способа для простой операции, основываясь на предположениях типа значения, таких как «здесь я определенно преобразую число в строку и здесь определенно логическое значение в строку».

Объяснение:

String(x)обрабатывает null, undefined, Symbols, [что угодно] и вызывает .toString()объекты.

'' + xвызовы .valueOf()по x (приведение к числу), броски по символам могут обеспечить результаты, зависящие от реализации.

x.toString() бросает в нули и неопределенный.

Примечание: String(x)все равно не будет работать на объектах без прототипов, таких как Object.create(null).

Если вам не нравятся строки типа «Hello, undefined» или вы хотите поддерживать объекты без прототипов, используйте следующую функцию преобразования типов:

/**
 * Safely casts any value to string. Null and undefined are converted to ''.
 * @param  {*} value
 * @return {string}
 */
function string (str) {
  return value == null ? '' : (typeof value === 'object' && !value.toString ? '[object]' : String(value));
}
Александр Шостак
источник
1

С помощью числовых литералов точка для доступа к свойству должна отличаться от десятичной точки. Это оставляет вам следующие опции, если вы хотите вызвать String () для числового литерала 123:

123..toString()
123 .toString() // space before the dot 123.0.toString()
(123).toString()
Мохит Дабас
источник
1

Ниже приведены методы для преобразования целого числа в строку в JS

Методы расположены в порядке убывания производительности.

(Результаты теста производительности приведены @DarckBlezzer в своем ответе)

var num = 1

Способ 1:

num = `$ {num}`

Способ 2:

num = num + ''

Способ 3:

num = String (num)

Способ 4:

num = num.toString ()

Примечание: вы не можете напрямую вызвать tostring () с номера

Например: 2.toString () сгенерирует Uncaught SyntaxError : неверный или неожиданный токен

Арун Джошла
источник
0

Если вам интересно, какой из них наиболее эффективен, проверьте это, где я сравниваю все различные преобразования числа -> строки.

Похоже 2+''или 2+""самые быстрые.

https://jsperf.com/int-2-string

Алекс Кори
источник
0

Мы также можем использовать конструктор String . Согласно этому тесту, это самый быстрый способ конвертировать Number в String в Firefox 58, хотя он и медленнее, чем " + numв популярном браузере Google Chrome.

peterchaula
источник
0

Метод toFixed()также решает цель.

var n = 8.434332;
n.toFixed(2)  // 8.43
Шайк Расул
источник
0

Вы можете вызвать Numberобъект, а затем позвонить toString().

Number.call(null, n).toString()

Вы можете использовать этот трюк для других нативных объектов javascript.

ufadiz
источник
0

Просто сталкивайтесь с этим недавно, методы 3 и 4 не подходят, потому что, как строки копируются, а затем соединяются. Для небольшой программы эта проблема незначительна, но для любого реального веб-приложения это действие, в котором мы имеем дело с манипуляциями с частотными строками, может повлиять на производительность и удобочитаемость.

Вот ссылка для чтения .

Роджер
источник
0

Я собираюсь отредактировать это с большим количеством данных, когда у меня будет время, потому что сейчас все в порядке ...

Тест в nodejs v8.11.2: 2018/06/06

let i=0;
    console.time("test1")
    for(;i<10000000;i=i+1){
    	const string = "" + 1234;
    }
    console.timeEnd("test1")
    
    i=0;
    console.time("test1.1")
    for(;i<10000000;i=i+1){
    	const string = '' + 1234;
    }
    console.timeEnd("test1.1")
    
    i=0;
    console.time("test1.2")
    for(;i<10000000;i=i+1){
    	const string = `` + 1234;
    }
    console.timeEnd("test1.2")
    
    i=0;
    console.time("test1.3")
    for(;i<10000000;i=i+1){
    	const string = 1234 +  '';
    }
    console.timeEnd("test1.3")
    
    
    i=0;
    console.time("test2")
    for(;i<10000000;i=i+1){
    	const string = (1234).toString();
    }
    console.timeEnd("test2")
    
    
    i=0;
    console.time("test3")
    for(;i<10000000;i=i+1){
    	const string = String(1234);
    }
    console.timeEnd("test3")
    
    
    i=0;
    console.time("test4")
    for(;i<10000000;i=i+1){
    	const string = `${1234}`;
    }
    console.timeEnd("test4")
    
    i=0;
    console.time("test5")
    for(;i<10000000;i=i+1){
    	const string = 1234..toString();
    }
    console.timeEnd("test5")
    
    i=0;
    console.time("test6")
    for(;i<10000000;i=i+1){
    	const string = 1234 .toString();
    }
    console.timeEnd("test6")

вывод

test1: 72.268ms
test1.1: 61.086ms
test1.2: 66.854ms
test1.3: 63.698ms
test2: 207.912ms
test3: 81.987ms
test4: 59.752ms
test5: 213.136ms
test6: 204.869ms
DarckBlezzer
источник
Yay - test4 - это то, что я регулярно использую !!
Адриан Варфоломей
0

Похоже, аналогичные результаты при использовании node.js. Я запустил этот скрипт:

let bar;
let foo = ["45","foo"];

console.time('string concat testing');
for (let i = 0; i < 10000000; i++) {
    bar = "" + foo;
}
console.timeEnd('string concat testing');


console.time("string obj testing");
for (let i = 0; i < 10000000; i++) {
    bar = String(foo);
}
console.timeEnd("string obj testing");

console.time("string both");
for (let i = 0; i < 10000000; i++) {
    bar = "" + foo + "";
}
console.timeEnd("string both");

и получил следующие результаты:

 node testing.js
string concat testing: 2802.542ms
string obj testing: 3374.530ms
string both: 2660.023ms

Подобные времена каждый раз, когда я запускал его.

Shahaed
источник