Який найкращий спосіб перетворити число в рядок у JavaScript?


517

Який "найкращий" спосіб перетворення числа в рядок (з точки зору переваги швидкості, переваги ясності, переваги пам'яті тощо)?

Деякі приклади:

  1. String(n)

  2. n.toString()

  3. ""+n

  4. n+""

Відповіді:


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зразок.


58
Є випадки , коли перетворення не може повертати кращий відповідь: '' + 123e-50повертається "1.23e-48".
hongymagic

21
@hongymagic: ця відповідь насправді є єдиною можливою: число не хвилює і не знає, як воно було введено, а стандартне друковане представлення має рівно одну цифру перед крапкою.
Svante

4
Я проходив тест у jsben.ch/ghQYR , кожен раз, коли він показує мені інший результат!
Maryam Saeidi

2
Мені подобається ця відповідь, тому null fooщо помилка не кидає.
ttugates

2
@MaryamSaeidi: Використання тесту jsperf.com з drublic вище, здається, більш послідовним.
Гіральді

364

На мою думку, n.toString()премію отримує за свою чіткість, і я не думаю, що вона несе зайвих витрат.


Він має певні накладні витрати, хоча він є незначним в останніх версіях браузера. Принаймні, у Firefox Quantum
peterchaula

11
Це небезпечно. n може бути нульовим або невизначеним.
david.pfx

20
@ david.pfx у запитанні задається питання, як перетворити числові значення в рядок. Надання прикладів нечислових значень (наприклад null, undefined), які не працюють з цією відповіддю, навряд чи робить це "небезпечним".
Майкл Мартін-Смукер

5
@ MichaelMartin-Smucker: Якщо ти пишеш багато JS, ти розумієш, що речі рідко так ріжуться і сушаться. Питання було відкритим, і хороша відповідь ІМО повинна хоча б визнати питання про рядок, який насправді є недійсним або невизначеним. 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).
Rik Martins

2
String (null) не збиває прогаму, але він поверне буквальний рядок "null", який, мабуть, не є тим, що потрібно. Якщо дані могли законно бути недійсними, тоді вам потрібно явно обробляти їх.
Пітер Смарт

1
@MattWallis Я думаю, що це повинно бути рішенням розробника, а не відповідача, ти не вважаєш?
forresthopkinsa

30

... Аналізатор 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}`;

Якщо я запускаю орієнтири за допомогою шаблонів ES6, іноді це навіть виявляється швидшим, ніж '' + numberметод. Слід сказати, що результати цих орієнтирів сильно відрізняються при їх виконанні кілька разів, тому не впевнені, чи слід їх сприймати занадто серйозно.
Ніко Ван Белль

15

Інші відповіді вже охоплювали інші варіанти, але я віддаю перевагу цьому:

s = `${n}`

Короткий, короткий, вже використовується в багатьох інших місцях (якщо ви використовуєте сучасну версію фреймворку / ES), тому це безпечна ставка, будь-який програміст це зрозуміє.

Мало того, що це (як правило) має велике значення, але воно, здається, є одним із найшвидших у порівнянні з іншими методами .


Це також безпечно, якщо n може бути не числом.
david.pfx

Але це так n.toString(), чи не так?
amn

1
@amn, якщо nце, undefinedто він видасть синтаксичну помилку, використовуючи.toString()
Jee

Це не дає лише такого ж результату, як String(n)у всіх випадках? Різниця лише в тому, що це менш зрозуміло.
Bennett McElwee

І набагато повільніше.
Адріан Варфоломій

12

Найпростіший спосіб перетворення будь-якої змінної в рядок - це додати порожню рядок до цієї змінної.

5.41 + ''    // Result: the string '5.41'
Math.PI + '' // Result: the string '3.141592653589793'

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-compitation

Станом на 24 липня 2018 року результати свідчать про те number + '', що найшвидший у Chrome, у Firefox, який зв’язується з літеральними рядками шаблону.

І те String(number), і number.toString()на 95% повільніше, ніж найшвидший варіант.

тести на ефективність, опис вище


2

Мені подобаються перші два, оскільки їх легше читати. Я схильний використовувати, String(n)але це лише питання стилю, ніж все інше.

Тобто, якщо у вас немає рядка як

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

що дуже пояснює себе


2

Я думаю, це залежить від ситуації, але все одно ви можете використовувати .toString()метод, оскільки це дуже зрозуміло.


2

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


1

Якщо мені довелося б все взяти до уваги, я пропоную наступне

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

IMHO - це найшвидший спосіб перетворення на рядок. Виправте мене, якщо я помиляюся.


1

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

Пояснення:

String(x)обробляє нулі, невизначені символи, [що-небудь] та викликає .toString()об'єкти.

'' + xдзвінки .valueOf()на x (переклад на номер), кидки на Symbols, можуть забезпечити залежні від реалізації результати.

x.toString() кидає на нулі та невизначено.

Примітка: String(x)усе ще не вдасться на об'єкти, що не мають прототипу, як-от Object.create(null).

Якщо вам не подобаються рядки типу "Привіт, невизначено" або ви хочете підтримувати об'єкти без прототипу, використовуйте наступну функцію перетворення типу:

/**
 * 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

Нижче наведено способи перетворення цілого числа в String в JS

Методи розташовані в порядку зменшення продуктивності.

(Результати тесту на продуктивність надає @DarckBlezzer у своїй відповіді)

var num = 1

Спосіб 1:

num = `$ {num}`

Спосіб 2:

num = num + ''

Спосіб 3:

num = Рядок (num)

Спосіб 4:

num = num.toString ()

Примітка: Ви не можете безпосередньо дзвонити tostring () з номера

Напр .: 2.toString () викине Uncaught SyntaxError : Недійсний або несподіваний маркер



0

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



0

Ви можете зателефонувати в Numberоб'єкт, а потім подзвонити toString().

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

Ви можете використовувати цей трюк для інших власних об’єктів javascript.


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

Так - тест4 - це те, що я регулярно використовую !!
Адріан Варфоломій

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.