Casting su stringa in JavaScript


184

Ho trovato tre modi per trasmettere una variabile Stringin JavaScript.
Ho cercato queste tre opzioni nel codice sorgente di jQuery e sono tutte in uso .
Vorrei sapere se ci sono differenze tra loro:

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

DEMO

Tutti producono lo stesso risultato, ma uno di loro è migliore degli altri?
Direi che + ""ha il vantaggio di salvare alcuni personaggi, ma non è questo il grande vantaggio, nient'altro?


1
Mi sembra che se tutte le cose fossero uguali, lo standard toString()sarebbe la strada da percorrere.
asawyer,

1
@asawyer. E perché? Se tutti producono lo stesso output e fanno lo stesso, scegline uno e seguilo. Questa è la mia opinione se questo è davvero il caso qui .
gdoron sostiene Monica il

1
I primi due metodi dovrebbero essere equivalenti (dovresti controllare lo standard ma il costruttore chiamerà String). Il terzo USUALMENTE produce lo stesso output ma comporta un meccanismo molto diverso (oltre alla velocità comporta chiamate diverse quindi potrebbe non essere quello che ti aspetti per ogni tipo di oggetto).
Adriano Repetti,

6
Secondo me toStringè semanticamente il modo più chiaro per documentare autonomamente il fatto che stai cercando di ottenere una stringa equivalente di un oggetto. String(...)è un po 'ottuso, ed value + ""è un po' un trucco. Ti dà anche la possibilità di sovrascrivere il default toStringcon un'implementazione personalizzata se mai dovessi supporre, come un vantaggio secondario.
asawyer,

2
@Adriano. Ma + ""è il più veloce secondo jsperf, quindi ... lo fa in qualche altro modo immagino.
gdoron sostiene Monica il

Risposte:


213

Si comportano diversamente quando lo valueè null.

  • null.toString()genera un errore - Impossibile chiamare il metodo 'toString' di null
  • String(null)restituisce - "null"
  • null + ""restituisce anche - "null"

Un comportamento molto simile si verifica se lo valueè undefined(vedi la risposta di jbabey ).

Oltre a ciò, c'è una differenza di prestazioni trascurabile, che, a meno che non li si usi in loop enormi, non vale la pena preoccuparsi.


Questa è in realtà una differenza interessante. Quindi dovresti astenersi dall'utilizzare toString()quando non hai ancora verificato null.
Sammy S.

@SammyS. non so se la stampa nullo undefinedsullo schermo sia un comportamento più desiderabile di un errore javascript ...
Justus Romijn,

@JustusRomijn: vero davvero. Nel frattempo, ho iniziato a utilizzare il tipo di opzione per gestire tali errori.
Sammy S.

puoi controllare una qualsiasi di queste variabili espresse con typeof per verificare la presenza di stringhe. typeof (null + '') == 'string'
Bruce Lim

4
C'è un altro caso in cui si comportano diversamente. v + ''restituisce un risultato errato se v ha entrambi i metodi toString () e valueOf (). La concatenazione ignorerà toString () e utilizzerà valueOf (). Esempio di una classe per la quale la concatenazione fallisce: github.com/processing-js/processing-js/blob/…
Mikita Belahlazau

26

Ci sono differenze, ma probabilmente non sono rilevanti per la tua domanda. Ad esempio, il prototipo toString non esiste su variabili non definite, ma è possibile eseguire il cast non definito su una stringa utilizzando gli altri due metodi:

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/


3
Se una variabile non è affatto definita, verrà comunque visualizzato un errore per String(). Esempio: String(test);genera Uncaught ReferenceError: test is not defined, mentre var test; String(test);si tradurrà in "undefined".
Anthony,

17

Si comportano allo stesso modo ma toStringforniscono anche un modo per convertire un numero di stringhe binarie, ottali o esadecimali:

Esempio:

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

9

Secondo questo test JSPerf , differiscono in velocità. Ma a meno che non li userai in grandi quantità, nessuno di loro dovrebbe funzionare bene.

Per completezza: come già accennato in Asawyer , puoi anche usare il .toString()metodo.


2
Quel jsperf ha ripetuto lo stesso test due volte, l' ho modificato E new String()restituisce un oggetto non unString
gdoron supporta Monica il

new String()restituisce un oggetto sì. String(), tuttavia, restituisce una stringa, che è quella nella domanda.
Connell,

2
Questo non è del tutto vero. Come puoi vedere dai risultati, concatenare una stringa vuota e un oggetto non produce lo stesso risultato della concatenazione di un oggetto e una stringa vuota. Inoltre, new String(blarg)ti dà un Stringoggetto su cui puoi invocare toString(). Nel mio debugger di Chrome, risultano effettivamente lo stesso tipo di oggetto tranne detta differenza.
Sammy S.

@SammyS. Potresti aggiungere esempi di risultati prestazionali alla tua risposta? Il collegamento jsperf attualmente non funziona e sicuramente lo sarà di nuovo nei prossimi 5 anni.
mxmlnkn,

9

Oltre a tutto quanto sopra, si dovrebbe notare che, per un valore definito v:

  • String(v) chiamate v.toString()
  • '' + vchiamate v.valueOf()prima di qualsiasi altro tipo cast

Quindi potremmo fare qualcosa del tipo:

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

Testato in FF 34.0 e Nodo 0.10


8

se stai bene con null, indefinito, NaN, 0 e false tutto il cast su '' allora (s ? s+'' : '')è più veloce.

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

nota: al momento ci sono differenze significative tra i browser.


4

Esempio pratico: ho una funzione di log che può essere chiamata con un numero arbitrario di parametri: log("foo is {} and bar is {}", param1, param2). Se un DEBUGflag è impostato su true, le parentesi vengono sostituite dai parametri indicati e la stringa viene passata a console.log(msg). I parametri possono e saranno stringhe, numeri e qualsiasi cosa possa essere restituita dalle chiamate JSON / AJAX, forse anche null.

  • arguments[i].toString()non è un'opzione, a causa dei possibili nullvalori (vedere la risposta di Connell Watkins)
  • JSLint si lamenterà arguments[i] + "". Questo può o meno influenzare una decisione su cosa usare. Alcune persone aderiscono rigorosamente a JSLint.
  • In alcuni browser, concatenare stringhe vuote è un po 'più veloce rispetto all'utilizzo della funzione stringa o del costruttore di stringhe (vedi test JSPerf nella risposta di Sammys S.). In Opera 12 e Firefox 19, concatenare stringhe vuote è ridicolmente più veloce (95% in Firefox 19) - o almeno lo dice JSPerf .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.