Какой "лучший" способ преобразования числа в строку (с точки зрения скорости, преимущества ясности, преимущества памяти и т.д.)?
Некоторые примеры:
-
String(n)
-
n.toString()
-
""+n
-
n+""
Какой "лучший" способ преобразования числа в строку (с точки зрения скорости, преимущества ясности, преимущества памяти и т.д.)?
Некоторые примеры:
String(n)
n.toString()
""+n
n+""
вот так:
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
.
По-моему n.toString()
получает приз за его ясность, и я не думаю, что он несет дополнительные накладные расходы.
Явные конверсии очень понятны для тех, кто знаком с языком. Использование принуждения типа, как предполагали другие, приводит к двусмысленности, если разработчику не известно о правилах принуждения. В конечном счете, время разработки более дорогое, чем процессорное время, поэтому я бы оптимизировал его раньше за счет последних. При этом разница в этом случае, вероятно, незначительна, но если нет, то я уверен, что есть некоторые достойные компрессоры JavaScript, которые будут оптимизировать такие вещи.
Итак, по вышеуказанным причинам я бы пошел с: n.toString()
или String(n)
. String(n)
, вероятно, лучший выбор, потому что он не сбой, если n
имеет значение null или undefined.
... парсер JavaScript пытается разобрать точечная запись числа как литерала с плавающей точкой.
2..toString(); // the second point is correctly recognized
2 .toString(); // note the space left to the dot
(2).toString(); // 2 is evaluated first
Язык в щеке, очевидно:
var harshNum = 108;
"".split.call(harshNum,"").join("");
Или в ES6 вы можете просто использовать строки шаблона:
var harshNum = 108;
`${harshNum}`;
Самый простой способ преобразования любой переменной в строку - это добавить пустую строку к этой переменной.
5.41 + '' // Result: the string '5.41'
Math.PI + '' // Result: the string '3.141592653589793'
Другие ответы уже охватывали другие варианты, но я предпочитаю этот:
s = '${n}'
Коротко, кратко, уже используется во многих других местах (если вы используете современную фреймворк /ES-версию), так что это безопасная ставка, любой программист поймет это.
Не то чтобы это (обычно) имело большое значение, но оно также оказалось одним из самых быстрых по сравнению с другими методами.
Если вам нужно отформатировать результат с определенным числом десятичных знаков, например, для представления валюты, вам нужно что-то вроде метода toFixed()
.
number.toFixed( [digits] )
digits
- количество цифр, отображаемых после десятичного знака.
Мне нравятся первые два, так как их легче читать. Я использую String(n)
, но это только вопрос стиля, чем что-либо еще.
То есть, если у вас нет строки как
var n = 5;
console.log ("the number is: " + n);
который очень самоочевиден
Я думаю, что это зависит от ситуации, но в любом случае вы можете использовать метод .toString()
, поскольку это очень понятно для понимания.
Я использовал 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% медленнее, чем самая быстрая опция.
.toString() - встроенная функция приведения типов, я не разбираюсь в этих деталях, но всякий раз, когда мы сравниваем встроенные методы приведения типов к явным методам, всегда предпочтительнее встроенные обходные пути.
Если бы мне пришлось принять все во внимание, я предложу следующее
var myint = 1;
var mystring = myint + '';
/*or int to string*/
myint = myint + ''
IMHO, это самый быстрый способ конвертировать в строку. Исправьте меня, если я ошибаюсь.
Единственное допустимое решение для почти всех возможных существующих и будущих случаев (входные данные - число, ноль, неопределенное значение, символ и все остальное) - это String(x)
. Не используйте 3 способа для простой операции, основываясь на предположениях типа значения, таких как "здесь я определенно преобразую число в строку и здесь определенно логическое значение в строку".
Объяснение:
String(x)
обрабатывает нулевые, неопределенные, символы, [что угодно] и вызывает .toString()
для объектов.
'' + x
вызывает .valueOf()
для x (приведение к числу), .valueOf()
символы, может обеспечить результаты, зависящие от реализации.
x.toString()
выбрасывает значение 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));
}
Если вам интересно, какая из них наиболее эффективна, проверьте, где я сравниваю все различные преобразования Number → String.
Похоже, 2+''
или 2+""
являются самыми быстрыми.
Мы также можем использовать конструктор String. Согласно этому эталону это самый быстрый способ конвертировать Number в String в Firefox 58, хотя он медленнее, чем " + num
в популярном браузере Google Chrome.
Метод toFixed()
также решает цель.
var n = 8.434332;
n.toFixed(2) // 8.43
Вы можете вызвать объект Number
а затем вызвать toString()
.
Number.call(null, n).toString()
Вы можете использовать этот трюк для других собственных объектов javascript.
Просто натолкнувшись на это недавно, методы 3 и 4 не подходят, потому что, как строки копируются, а затем собираются вместе. Для небольшой программы эта проблема незначителен, но для любого реального веб-приложения это действие, в котором мы имеем дело с манипуляциями с частотной строкой, может влиять на производительность и читаемость.
Я собираюсь переделать это с большим количеством данных, когда у меня будет время, потому что сейчас это прекрасно...
Тест в 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")
Аналогичные результаты возникают при использовании 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
Подобные времена каждый раз я запускал его.
С помощью числовых литералов точка для доступа к свойству должна отличаться от десятичной точки. Это оставляет вам следующие опции, если вы хотите вызвать String() для числового литерала 123:
123..toString()
123 .toString() // space before the dot 123.0.toString()
(123).toString()