¿Cuál es la mejor manera de convertir un número en una cadena en JavaScript?

611

¿Cuál es la "mejor" forma de convertir un número en una cadena (en términos de ventaja de velocidad, ventaja de claridad, ventaja de memoria, etc.)?

Algunos ejemplos:

  1. String(n)

  2. n.toString()

  3. ""+n

  4. n+""

1
  • Esta pregunta me parece bastante clara. qwr 3 de agosto a las 9:27
626

como esto:

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

En realidad, aunque normalmente lo hago así por simple conveniencia, en más de 1000 iteraciones parece que para la velocidad bruta hay una ventaja para.toString()

Vea las pruebas de rendimiento aquí (no por mí, pero las encontré cuando fui a escribir las mías): http://jsben.ch/#/ghQYR

Más rápido según la prueba JSPerf anterior: str = num.toString();

Cabe señalar que la diferencia de velocidad no es demasiado significativa si se considera que puede realizar la conversión de cualquier forma 1 millón de veces en 0,1 segundos .

Actualización: la velocidad parece variar mucho según el navegador. En Chrome num + ''parece ser el más rápido según esta prueba http://jsben.ch/#/ghQYR

Actualización 2: De nuevo, según mi prueba anterior, debe tenerse en cuenta que Firefox 20.0.1 ejecuta .toString()aproximadamente 100 veces más lento que la '' + nummuestra.

9
  • sesenta y cinco
    Hay casos en los que la conversión puede no devolver una respuesta preferible: '' + 123e-50devoluciones "1.23e-48". hongymagic 30/10/2013 a las 6:35
  • 26
    @hongymagic: esa respuesta es de hecho la única concebible: al número no le importa ni sabe cómo se ingresó, y la representación impresa estándar es exactamente con un dígito antes del punto. Svante 2 de septiembre de 2015 a las 18:32
  • 4
    Ejecuté la prueba en jsben.ch/ghQYR , ¡cada vez que me muestra un resultado diferente! Maryam Saeidi 16 de agosto de 2017 a las 12:39
  • 2
    Me gusta esta respuesta porque null foono arroja un error. ttugates 17/11/2017 a las 18:41
  • 2
    @MaryamSaeidi: Usando Drublic 's jsperf.com prueba anterior parece más consistente. Giraldi 21/04/18 a las 9:38
413

En mi opinión, se n.toString()lleva el premio por su claridad, y no creo que conlleve ningún gasto adicional.

8
  • 17
    Esto no es seguro. n puede ser nulo o indefinido. david.pfx 13/11/18 a las 10:11
  • 40
    @ david.pfx la pregunta pregunta cómo convertir valores numéricos en una cadena. Proporcionar ejemplos de valores no numéricos (por ejemplo null, undefined) que no funcionan con esta respuesta difícilmente lo hace "inseguro". Michael Martin-Smucker 2/12/18 a las 23:24
  • 6
    @ MichaelMartin-Smucker: Si escribe mucho JS, se da cuenta de que las cosas rara vez están tan cortadas y secas. La pregunta estaba abierta y, en mi opinión, una buena respuesta debería al menos reconocer el problema de una cadena que en realidad es nula o indefinida. YMMV. david.pfx 19 feb 2019 a las 22:37
  • 1
    @ david.pfx He escrito MUCHOS js y no recuerdo la última vez que necesité un número como cadena y cualquier cosa menos un número como cadena habría sido suficiente. Esta es la respuesta correcta. No hay respuesta al manejo nullo undefinedcomo es específico de la aplicación, aunque imagino que (n || defaultNumber).toString() es lo que la mayoría de la gente querría en una situación así, estoy totalmente en desacuerdo en que deberíamos estar trabajando en todas las preguntas. Se trataba de convertir números en cadenas, una buena arquitectura y otras conversiones de tipos donde se necesitaban lecciones separadas. George Reith 23 abr.20 a las 12:41
  • 5
    @ david.pfx ¿qué certeza? mi punto fue que no hay respuesta nullo undefined, no arrojar un error no es manejarlo y ocultarlo también hará que "el código falle". No aprecio sus declaraciones condescendientes como "tal vez es hora de escribir menos código y leer más", le aconsejo que se mantenga ad hominem fuera de su argumento y felizmente lo pasaré por alto esta vez. George Reith 27 abr.20 a las 9:40
86

Las conversiones explícitas son muy claras para alguien que es nuevo en el idioma. El uso de la coerción de tipos, como han sugerido otros, conduce a la ambigüedad si un desarrollador no conoce las reglas de coerción. En última instancia, el tiempo del desarrollador es más costoso que el tiempo de la CPU, por lo que optimizaría el primero a costa del segundo. Dicho esto, en este caso la diferencia probablemente sea insignificante, pero si no, estoy seguro de que hay algunos compresores JavaScript decentes que optimizarán este tipo de cosas.

Entonces, por las razones anteriores, iría con: n.toString()o String(n). String(n)es probablemente una mejor opción porque no fallará si nes nulo o indefinido.

4
  • 14
    La pregunta era sobre la conversión de números, no sobre la conversión de números o null, o undefined. Si nes nullo se undefineddebe a un error en mi programa, entonces preferiría que mi programa fallara en este estado, para darme una mejor oportunidad de encontrar y corregir el error. Los bloqueos del programa son regalos para el programador, para ayudarla a encontrar los errores :-). La alternativa es entregar software que no funcione como se diseñó, habiendo pasado por alto cuidadosamente los errores. Entonces, no soy un fanático del uso String(n)para enmascarar un error. Matt Wallis 22 de septiembre de 2015 a las 12:12
  • 2
    String(n)es bueno para usar en un estilo funcional, por ejemplo, con una combinación de subrayado _.compose(funcThatNeedsAStringParam, String). Rik Martins 17/04/2017 a las 14:21
  • 4
    String (null) no bloqueará el programa, pero devolverá la cadena literal "null", que probablemente no sea lo que desea. Si los datos pueden ser legítimamente nulos, entonces debe manejarlos explícitamente. Peter Smartt 23 de mayo de 2017 a las 1:35
  • 1
    @MattWallis Creo que esa debería ser la decisión del desarrollador, no del que responde, ¿no crees? forresthopkinsa 21/12/18 a las 17:48
37

...JavaScript's parser tries to parse the dot notation on a number as a floating point literal.

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

Fuente

27

Otras respuestas ya cubrieron otras opciones, pero prefiero esta:

s = `${n}`

Breve, conciso, ya se utiliza en muchos otros lugares (si está utilizando un marco moderno / versión ES), por lo que es una apuesta segura que cualquier programador lo entenderá.

No es que (por lo general) importe mucho, pero también parece estar entre los más rápidos en comparación con otros métodos .

6
  • También es seguro si n no es un número. david.pfx 13/11/18 a las 10:13
  • Pero también lo es n.toString()entonces, ¿no? amn 24 de mayo de 2019 a las 13:21
  • 1
    @amn si lo nes undefined, arrojará un error de sintaxis al usar.toString()Jee Mok 8/11/19 a las 0:18
  • 1
    ¿No da esto el mismo resultado que String(n)en todos los casos? La única diferencia es que es menos claro. Bennett McElwee 19/11/19 a las 0:03
  • 1
    Y mucho más lento. Adrian Bartholomew 7 de ene. De 2020 a las 3:04
22

El abajo son los métodos para convertir una Integera Stringen JS.

Los métodos están ordenados en orden decreciente de ejecución.

var num = 1

Método 1:

num = `${num}`

Método 2:

num = num + ''

Método 3:

num = String(num)

Método 4:

num = num.toString()

Nota: no puede llamar directamente toString()a un número. 2.toString()arrojará Uncaught SyntaxError: Invalid or unexpected token.

(Los resultados de la prueba de rendimiento los da @DarckBlezzer en su respuesta)

21

Lengua en la mejilla, obviamente:

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

O en ES6, simplemente podría usar cadenas de plantilla :

var harshNum = 108;
`${harshNum}`;
1
  • Si ejecuto los puntos de referencia con plantillas ES6, a veces incluso resulta ser más rápido que el '' + numbermétodo. Dicho esto, los resultados de estos puntos de referencia varían mucho al realizarlos varias veces, por lo que no estoy seguro de si deben tomarse demasiado en serio. Nico Van Belle 20/04/18 a las 9:28
12

La forma más sencilla de convertir cualquier variable en una cadena es agregar una cadena vacía a esa variable.

5.41 + ''    // Result: the string '5.41'
Math.PI + '' // Result: the string '3.141592653589793'
2
  • 2
    Tenga en cuenta que debe estar dentro de los parens: (5.41 + '')para usar los métodos String como .substring()y otrosGjaa 2 de abril de 2016 a las 4:47
  • 1
    ¿Por qué hay que tenerlo en cuenta? Adrian Bartholomew 7 de ene. De 2020 a las 3:08
10

Usé https://jsperf.com para crear un caso de prueba para los siguientes casos:

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

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

A partir del 24 de julio de 2018, los resultados dicen que number + ''es el más rápido en Chrome, en Firefox que se vincula con los literales de cadena de plantilla.

Ambos String(number), y number.toString()son aproximadamente un 95% más lentos que la opción más rápida.

pruebas de rendimiento, descripción arriba

6

Si necesita formatear el resultado a un número específico de posiciones decimales, por ejemplo, para representar la moneda, necesita algo como el toFixed()método.

number.toFixed( [digits] )

digits es el número de dígitos que se mostrarán después del decimal.

1
  • 2
    Inseguro a menos que sepa que es un número. david.pfx 13/11/18 a las 10:13
3

Con literales numéricos, el punto para acceder a una propiedad debe distinguirse del punto decimal. Esto le deja con las siguientes opciones si desea invocar a String () en el número literal 123:

123..toString()
123 .toString() // space before the dot 123.0.toString()
(123).toString()
1
  • Básicamente interesante ver esto es posible. Pero aparte de eso, ¿cuál es un caso de uso beneficioso para hacer esta conversión en lugar de simplemente escribir "123"en primer lugar? Ni siquiera veo este caso enumerado explícitamente en la pregunta de OP. Como regla general: si ahora tiene el valor literal, simplemente póngalo entre comillas, ya que no se requiere ningún procesamiento. Thomas Urban 8 de septiembre de 2020 a las 9:49
2

Me gustan los dos primeros porque son más fáciles de leer. Tiendo a usarlo, String(n)pero es solo una cuestión de estilo que cualquier otra cosa.

Eso es a menos que tenga una línea como

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

que es muy autoexplicativo

2

Creo que depende de la situación, pero de todos modos puedes usar el .toString()método, ya que es muy claro de entender.

2

Voy a volver a editar esto con más datos cuando tenga tiempo, por ahora esto está bien ...

Prueba en nodejs v8.11.2: 06/06/2018

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")

producción

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
1
  • 1
    ¡¡¡Test4 es lo que uso habitualmente !! Adrian Bartholomew 7 de ene. De 2020 a las 3:03
2

La única solución válida para casi todos los casos posibles existentes y futuros (la entrada es número, nulo, indefinido, símbolo, cualquier otra cosa) es String(x). No use 3 formas para una operación simple, basándose en suposiciones de tipo de valor, como "aquí convierto definitivamente un número a una cadena y aquí definitivamente un booleano a una cadena".

Explicación:

String(x)maneja nulos, indefinidos, símbolos, [cualquier cosa] y llamadas .toString()a objetos.

'' + xllamadas .valueOf()a x (conversión a número), lanzamientos a símbolos, pueden proporcionar resultados dependientes de la implementación.

x.toString() arroja nulos e indefinidos.

Nota: String(x)aún fallará en objetos sin prototipos como Object.create(null).

Si no le gustan las cadenas como 'Hola, indefinido' o si desea admitir objetos sin prototipos, use la siguiente función de conversión de tipos:

/**
 * 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));
}
2

.toString () es la función de encasillado incorporada, no soy un experto en esos detalles, pero siempre que comparamos las metodologías explícitas de conversión de tipos incorporadas, siempre se prefieren las soluciones alternativas.

1

Si tuviera que tomarlo todo en consideración, sugeriría seguir

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

En mi humilde opinión, es la forma más rápida de convertir a cadena. Corrígeme si estoy equivocado.

0

Si tiene curiosidad sobre cuál es el más eficiente, consulte esto donde comparo todas las diferentes conversiones de Número -> Cadena.

Parece 2+''o 2+""es el más rápido.

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

0

También podemos usar el constructor String . Según este punto de referencia , es la forma más rápida de convertir un número en una cadena en Firefox 58, aunque es más lento que " + numen el popular navegador Google Chrome.

0

El método toFixed()también resolverá el propósito.

var n = 8.434332;
n.toFixed(2)  // 8.43
0

Puede llamar al Numberobjeto y luego llamar toString().

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

Puede utilizar este truco para otros objetos nativos de JavaScript.

0

Acabo de encontrar esto recientemente, los métodos 3 y 4 no son apropiados porque las cadenas se copian y luego se juntan. Para un programa pequeño, este problema es insignificante, pero para cualquier aplicación web real, esta acción en la que tenemos que lidiar con manipulaciones de cadenas de frecuencia puede afectar el rendimiento y la legibilidad.

Aquí está el enlace de la lectura .

0

Parece resultados similares cuando se usa node.js. Ejecuté este script:

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");

y obtuve los siguientes resultados:

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

Tiempos similares cada vez que lo ejecuté.

0

Se lo recomendé `${expression}`porque no necesita preocuparse por los errores.

[undefined,null,NaN,true,false,"2","",3].forEach(elem=>{
  console.log(`${elem}`, typeof(`${elem}`))
})

/* output
undefined string
null      string
NaN       string
true      string
false     string
2         string
          string
3         string
*/

A continuación puedes probar la velocidad. pero el orden afectará el resultado. (en StackOverflow) puede probarlo en su plataforma.

const testCases = [
  ["${n}", (n) => `${n}`], // 👈
  ['----', undefined],

  [`"" + n`, (n) => "" + n],
  [`'' + n`, (n) => '' + n],
  [`\`\` + n`, (n) => `` + n],
  [`n + ''`, (n) => n + ''],
  ['----', undefined],

  [`String(n)`, (n) =>  String(n)],
  ["${n}", (n) => `${n}`], // 👈

  ['----', undefined],
  [`(n).toString()`, (n) => (n).toString()],
  [`n.toString()`, (n) => n.toString()],

]

for (const [name, testFunc] of testCases) {
  if (testFunc === undefined) {
    console.log(name)
    continue
  }
  console.time(name)
  for (const n of [...Array(1000000).keys()]) {
    testFunc(n)
  }
  console.timeEnd(name)
}