Qual è il modo migliore per convertire un numero in una stringa in JavaScript?


519

Qual è il modo "migliore" per convertire un numero in una stringa (in termini di vantaggio di velocità, vantaggio di chiarezza, vantaggio di memoria, ecc.)?

Qualche esempio:

  1. String(n)

  2. n.toString()

  3. ""+n

  4. n+""

Risposte:


516

come questo:

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

In realtà, anche se in genere lo faccio in questo modo per comodità semplice, oltre 1.000 di iterazioni sembra per la velocità pura, c'è un vantaggio per.toString()

Vedi i test delle prestazioni qui (non da me, ma trovati quando sono andato a scrivere il mio): http://jsben.ch/#/ghQYR

Il più veloce in base al test JSPerf sopra: str = num.toString();

Va notato che la differenza di velocità non è eccessivamente significativa se si considera che può fare la conversione in qualsiasi modo 1 milione di volte in 0,1 secondi .

Aggiornare: la velocità sembra differire notevolmente in base al browser. In Chrome num + ''sembra essere il più veloce in base a questo test http://jsben.ch/#/ghQYR

Aggiornamento 2: Ancora una volta in base al mio test sopra, va notato che Firefox 20.0.1 esegue .toString()circa 100 volte più lentamente del '' + numcampione.


58
Ci sono casi in cui la conversione potrebbe non restituire una risposta preferibile: '' + 123e-50restituisce "1.23e-48".
hongymagic,

21
@hongymagic: quella risposta è in realtà l'unico concepibile: al numero non importa né sa come è stato inserito e la rappresentazione stampata standard è esattamente con una cifra prima del punto.
Svante,

4
Ho eseguito il test su jsben.ch/ghQYR , ogni volta che mi mostra un risultato diverso!
Maryam Saeidi,

2
Mi piace questa risposta perché a null foonon genera un errore.
ttugates,

2
@MaryamSaeidi: Usando drublic 's jsperf.com prova di cui sopra sembra più coerente.
Giraldi,

364

Secondo me n.toString()prende il premio per la sua chiarezza, e non credo che abbia costi aggiuntivi.


Presenta un certo sovraccarico anche se è insignificante nelle recenti versioni del browser. Almeno in Firefox Quantum
peterchaula il

11
Questo non è sicuro. n potrebbe essere nullo o indefinito.
david.pfx,

20
@ david.pfx la domanda chiede come convertire i valori numerici in una stringa. Fornire esempi di valori non numerici (ad es null. undefined) Che non funzionano con questa risposta difficilmente la rende "non sicura".
Michael Martin-Smucker,

5
@ MichaelMartin-Smucker: se scrivi un sacco di JS ti rendi conto che raramente le cose vengono tagliate e asciugate. La domanda era aperta e l'IMO una buona risposta dovrebbe almeno riconoscere il problema di una stringa che è in realtà nulla o indefinita. YMMV.
david.pfx,

@ david.pfx Ho scritto MOLTE js e non ricordo l'ultima volta in cui avevo bisogno di un numero come stringa e qualsiasi cosa tranne un numero come stringa sarebbe stato sufficiente. Questa è la risposta corretta Non esiste una risposta alla gestione nullo undefinedpoiché è specifica per l'applicazione, mentre immagino (n || defaultNumber).toString() sia ciò che la maggior parte delle persone vorrebbe in una situazione del genere. Sono fortemente in disaccordo sul fatto che dovremmo occuparci di tutte le domande. Si trattava di convertire i numeri in stringhe, una buona architettura e altre conversioni di tipo dove necessario sono lezioni separate.
George Reith

73

Le conversioni esplicite sono molto chiare per qualcuno che non conosce la lingua. L'uso della coercizione del tipo, come altri hanno suggerito, porta all'ambiguità se uno sviluppatore non è a conoscenza delle regole di coercizione. In definitiva, il tempo degli sviluppatori è più costoso del tempo della CPU, quindi ottimizzerei per il primo a costo del secondo. Detto questo, in questo caso la differenza è probabilmente trascurabile, ma se non sono sicuro ci sono alcuni compressori JavaScript decenti che ottimizzeranno questo genere di cose.

Quindi, per i motivi di cui sopra, vorrei andare con: n.toString()o String(n). String(n)è probabilmente una scelta migliore perché non fallirà se nè nullo o indefinito.


12
La domanda riguardava la conversione di numeri, non la conversione di numeri, oppure null, o undefined. Se nè nullo è undefineddovuto a un bug nel mio programma, preferirei che il mio programma fallisse in questo stato, per darmi una migliore possibilità di trovare e correggere il bug. Gli arresti anomali del programma sono regali per il programmatore, per aiutarla a trovare i bug :-). L'alternativa è fornire software che non funzioni come previsto, dopo aver accuratamente esaminato i bug. Quindi, non sono un fan dell'utilizzo String(n)per mascherare un errore.
Matt Wallis,

1
String(n)è utile per l'utilizzo in uno stile funzionale, ad es. con la combinazione di trattini bassi _.compose(funcThatNeedsAStringParam, String).
Rik Martins,

2
String (null) non bloccherà il programma, ma restituirà la stringa letterale "null", che probabilmente non è ciò che desideri. Se i dati potrebbero essere legittimamente nulli, è necessario gestirli in modo esplicito.
Peter Smartt,

1
@MattWallis Penso che dovrebbe essere la decisione dello sviluppatore, non del risponditore, non credi?
forresthopkinsa,

31

... Il parser di JavaScript tenta di analizzare la notazione punto su un numero come letterale in virgola mobile.

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

fonte


17

Lingua tosta ovviamente:

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

O in ES6 potresti semplicemente usare stringhe di template :

var harshNum = 108;
`${harshNum}`;

Se eseguo i benchmark con i modelli ES6, a volte si rivela persino più veloce del '' + numbermetodo. Detto questo, i risultati di questi benchmark variano molto quando li eseguono più volte, quindi non sono sicuro che debbano essere presi troppo sul serio.
Nico Van Belle,

15

Altre risposte già riguardavano altre opzioni, ma preferisco questa:

s = `${n}`

Breve, sintetico, già utilizzato in molti altri luoghi (se si utilizza un framework moderno / versione ES), quindi è una scommessa sicura che qualsiasi programmatore lo capirà.

Non che (di solito) importi molto, ma sembra anche essere tra i più veloci rispetto ad altri metodi .


È anche sicuro se n potrebbe non essere un numero.
david.pfx,

Ma così è n.toString(), no?
AMN

1
@amn if nis undefinedlancerà un errore di sintassi usando.toString()
Jee Mok

Questo non dà lo stesso risultato String(n)di tutti i casi? L'unica differenza è che è meno chiaro.
Bennett McElwee,

E molto più lento.
Adrian Bartholomew,

12

Il modo più semplice per convertire qualsiasi variabile in una stringa è aggiungere una stringa vuota a quella variabile.

5.41 + ''    // Result: the string '5.41'
Math.PI + '' // Result: the string '3.141592653589793'

2
Nota che deve essere all'interno di parentesi: (5.41 + '')per usare i metodi String come .substring()e altri
Gjaa

Perché questo deve essere notato?
Adrian Bartholomew,

7

Se è necessario formattare il risultato su un numero specifico di posizioni decimali, ad esempio per rappresentare la valuta, è necessario qualcosa di simile al toFixed()metodo.

number.toFixed( [digits] )

digits è il numero di cifre da visualizzare dopo il decimale.


2
Non sicuro a meno che tu non sappia che è un numero.
david.pfx,

6

Ho usato https://jsperf.com per creare un test case per i seguenti casi:

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

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

A partire dal 24 luglio 2018 i risultati lo dicono number + '' è il più veloce in Chrome, in Firefox che si lega ai valori letterali delle stringhe dei modelli.

Entrambi String(number), e number.toString()sono circa il 95% più lenti dell'opzione più veloce.

test delle prestazioni, descrizione sopra


2

Mi piacciono i primi due poiché sono più facili da leggere. Tendo a usareString(n) ma è solo una questione di stile di ogni altra cosa.

Questo a meno che tu non abbia una linea come

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

che è molto esplicativo


2

Penso che dipenda dalla situazione, ma è comunque possibile utilizzare il .toString()metodo in quanto è molto chiaro da capire.


2

.toString () è la funzione di typecasting integrata, non sono un esperto di quei dettagli, ma ogni volta che confrontiamo il cast di tipi integrati con metodologie esplicite, soluzioni alternative integrate sono sempre preferite.


1

Se dovessi prendere in considerazione tutto, suggerirò di seguire

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

IMHO, è il modo più veloce per convertire in stringa. Correggimi se sbaglio.


1

L'unica soluzione valida per quasi tutti i possibili casi esistenti e futuri (input è numero, null, non definito, simbolo, qualsiasi altra cosa) è String(x). Non utilizzare 3 modi per operazioni semplici, basandosi su ipotesi di tipo di valore, come "qui converto sicuramente il numero in stringa e qui sicuramente il valore booleano in stringa".

Spiegazione:

String(x)gestisce valori nulli, indefiniti, simboli, [nulla] e richiede .toString()oggetti.

'' + xle chiamate .valueOf()su x (trasmissione al numero), il lancio di simboli, possono fornire risultati dipendenti dall'implementazione.

x.toString() genera null e indefinito.

Nota: String(x)fallirà comunque su oggetti senza prototipo come Object.create(null).

Se non ti piacciono le stringhe come 'Hello, undefined' o desideri supportare oggetti senza prototipo, usa la seguente funzione di conversione del tipo:

/**
 * 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

Con i letterali numerici, il punto per accedere a una proprietà deve essere distinto dal punto decimale. Questo ti lascia con le seguenti opzioni se vuoi invocare String () sul numero 123 letterale:

123..toString()
123 .toString() // space before the dot 123.0.toString()
(123).toString()

1

Di seguito sono riportati i metodi per convertire un numero intero in stringa in JS

I metodi sono disposti in ordine decrescente di prestazione.

(I risultati del test delle prestazioni sono forniti da @DarckBlezzer nella sua risposta)

var num = 1

Metodo 1:

num = `$ {num}`

Metodo 2:

num = num + ''

Metodo 3:

num = String (num)

Metodo 4:

num = num.toString ()

Nota: non è possibile chiamare direttamente tostring () da un numero

Ad esempio: 2.toString () genererà Uncaught SyntaxError : token non valido o imprevisto



0

Possiamo anche usare il costruttore String . Secondo questo benchmark è il modo più veloce per convertire un numero in stringa in Firefox 58 anche se è più lento rispetto " + numal popolare browser Google Chrome.


0

Il metodo toFixed()risolverà anche lo scopo.

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

0

È possibile chiamare l' Numberoggetto e quindi chiamare toString().

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

Puoi usare questo trucco per altri oggetti nativi javascript.


0

Basta incontrarlo di recente, i metodi 3 e 4 non sono appropriati perché le stringhe vengono copiate e assemblate. Per un piccolo programma questo problema è insignificante, ma per qualsiasi vera applicazione web questa azione in cui dobbiamo occuparci delle manipolazioni delle stringhe di frequenza può influire sulle prestazioni e sulla leggibilità.

Ecco il link alla lettura .


0

Ho intenzione di ri-modificare questo con più dati quando ho tempo, per ora va bene ...

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

produzione

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

Yay - test4 è quello che uso regolarmente !!
Adrian Bartholomew,

0

Sembra risultati simili quando si utilizza node.js. Ho eseguito questo 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");

e ha ottenuto i seguenti risultati:

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

Simili volte ogni volta che l'ho eseguito.

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.