Який найкращий спосіб перетворити число в рядок у 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.