Transmitir a cadena en JavaScript

184

Encontré tres formas de convertir una variable Stringen JavaScript.
Busqué esas tres opciones en el código fuente de jQuery, y todas están en uso .
Me gustaría saber si hay alguna diferencia entre ellos:

value.toString()
String(value)
value + ""

MANIFESTACIÓN

Todos producen la misma salida, pero ¿uno de ellos es mejor que los demás?
Diría que + ""tiene la ventaja de que salva a algunos personajes, pero esa no es una gran ventaja, ¿algo más?

gdoron está apoyando a Monica
fuente
1
Me parece que si todas las cosas son iguales, el estándar toString()sería el camino a seguir.
asawyer
1
@asawyer. ¿Y por qué es eso? Si todos producen el mismo resultado y hacen lo mismo, elija uno y vaya con él. Esta es mi opinión si este es realmente el caso aquí .
gdoron está apoyando a Monica el
1
Los primeros dos métodos deben ser equivalentes (debe verificar el estándar, pero el constructor llamará a toString). El tercero usualmente produce la misma salida, pero involucra un mecanismo muy diferente (además de la velocidad, involucra diferentes llamadas, por lo que puede no ser lo que esperas para cada tipo de objeto).
Adriano Repetti
66
En mi opinión, toStringes semánticamente la forma más clara de auto documentar el hecho de que está tratando de obtener una cadena equivalente a un objeto. String(...)es un poco obtuso, y value + ""es un poco hack. También le da la posibilidad de anular el valor predeterminado toStringcon una implementación personalizada si alguna vez lo necesita, supongo, como un beneficio secundario menor.
asawyer
2
@Adriano. Pero + ""es el más rápido según el jsperf, así que ... lo hace de otra manera, supongo.
gdoron está apoyando a Monica el

Respuestas:

213

Se comportan de manera diferente cuando valuees así null.

  • null.toString()arroja un error - No se puede llamar al método 'toString' de nulo
  • String(null)devuelve - "nulo"
  • null + ""también devuelve - "nulo"

Un comportamiento muy similar ocurre si valuees así undefined(ver la respuesta de jbabey ).

Aparte de eso, hay una diferencia de rendimiento insignificante que, a menos que los esté utilizando en bucles enormes, no vale la pena preocuparse.

Connell
fuente
Esto es realmente una diferencia interesante. Por lo tanto, debe abstenerse de usar toString()cuando aún no lo haya verificado null.
Sammy S.
@SammyS. no sé si la impresión nullo undefineden la pantalla es un comportamiento más deseable que un error de JavaScript ...
Justus Romijn
@JustusRomijn: Cierto en verdad. Mientras tanto, comencé a usar el tipo de opción para manejar tales errores.
Sammy S.
Puede verificar cualquiera de estas variables fundidas con typeof para verificar la cadena. typeof (null + '') == 'string'
Bruce Lim
44
Hay otro caso cuando se comportan de manera diferente. v + ''devuelve un resultado incorrecto si v tiene los métodos toString () y valueOf (). La concatenación ignorará toString () y usará valueOf (). Ejemplo de una clase para la cual falla la concatenación: github.com/processing-js/processing-js/blob/…
Mikita Belahlazau
26

Hay diferencias, pero probablemente no sean relevantes para su pregunta. Por ejemplo, el prototipo toString no existe en variables indefinidas, pero puede convertir indefinido a una cadena utilizando los otros dos métodos:

var foo;

var myString1 = String(foo); // "undefined" as a string

var myString2 = foo + ''; // "undefined" as a string

var myString3 = foo.toString(); // throws an exception

http://jsfiddle.net/f8YwA/

jbabey
fuente
3
Si una variable no está definida, aún obtendrá un error para String(). Ejemplo: String(test);tiros Uncaught ReferenceError: test is not defined, mientras var test; String(test);que resultará en "undefined".
Anthony
17

Se comportan igual pero toStringtambién proporcionan una forma de convertir un número de cadenas binarias, octales o hexadecimales:

Ejemplo:

var a = (50274).toString(16)  // "c462"
var b = (76).toString(8)      // "114"
var c = (7623).toString(36)   // "5vr"
var d = (100).toString(2)     // "1100100"
Sarfraz
fuente
9

Según esta prueba de JSPerf , difieren en velocidad. Pero a menos que los vaya a usar en grandes cantidades, cualquiera de ellos debería funcionar bien.

Para completar: como ya se mencionó como un abogado , también puede usar el .toString()método.

Sammy S.
fuente
2
Ese jsperf tiene la misma prueba dos veces, lo edité Y new String()devuelve un objeto que no es unString
gdoron está apoyando a Monica el
new String()devuelve un objeto yes. String(), sin embargo, devuelve una cadena, que es la de la pregunta.
Connell
2
Esto no es enteramente verdad. Como puede ver en los resultados, concatenar una cadena vacía y un objeto no produce el mismo resultado que concatenar un objeto y una cadena vacía. Además, new String(blarg)le ofrece un Stringobjeto al que puede llamar toString(). En mi depurador de Chrome, resultan efectivamente el mismo tipo de objeto, excepto dicha diferencia.
Sammy S.
@SammyS. ¿Podría agregar ejemplos de resultados de rendimiento a su respuesta? El enlace jsperf actualmente está caído y seguramente volverá a estarlo en los próximos 5 años o más.
mxmlnkn
9

Además de todo lo anterior, se debe tener en cuenta que, para un valor definido v:

  • String(v) llamadas v.toString()
  • '' + vllamadas v.valueOf()antes de cualquier otro tipo de reparto

Entonces podríamos hacer algo como:

var mixin = {
  valueOf:  function () { return false },
  toString: function () { return 'true' }
};
mixin === false;  // false
mixin == false;    // true
'' + mixin;       // "false"
String(mixin)     // "true"

Probado en FF 34.0 y Nodo 0.10

Simone C.
fuente
8

si está de acuerdo con nulo, indefinido, NaN, 0 y falso todo el envío a '', entonces (s ? s+'' : '')es más rápido.

ver http://jsperf.com/cast-to-string/8

nota: existen diferencias significativas entre los navegadores en este momento.

jldec
fuente
4

Ejemplo del mundo real: Tengo una función de registro que se puede llamar con un número arbitrario de parámetros: log("foo is {} and bar is {}", param1, param2). Si DEBUGse establece un indicador en true, los corchetes se reemplazan por los parámetros dados y se pasa la cadena a console.log(msg). Los parámetros pueden y serán cadenas, números y lo que sea que las llamadas JSON / AJAX puedan devolver, tal vez incluso null.

  • arguments[i].toString()no es una opción, debido a los posibles nullvalores (vea la respuesta de Connell Watkins)
  • JSLint se quejará arguments[i] + "". Esto puede o no influir en una decisión sobre qué usar. Algunas personas se adhieren estrictamente a JSLint.
  • En algunos navegadores, la concatenación de cadenas vacías es un poco más rápida que el uso de la función de cadena o el constructor de cadenas (consulte la prueba JSPerf en la respuesta de Sammys S.). En Opera 12 y Firefox 19, la concatenación de cadenas vacías es ridículamente más rápida (95% en Firefox 19) , o al menos JSPerf lo dice.
Jack
fuente
1

En esta página puede probar el rendimiento de cada método usted mismo :)

http://jsperf.com/cast-to-string/2

aquí, en todas las máquinas y navegadores, ' "" + str ' es el más rápido, (String) str es el más lento

itinerario
fuente