Quelle est la meilleure façon de convertir un nombre en chaîne en JavaScript?


519

Quelle est la "meilleure" façon de convertir un nombre en une chaîne (en termes d'avantage de vitesse, de clarté, de mémoire, etc.)?

Quelques exemples:

  1. String(n)

  2. n.toString()

  3. ""+n

  4. n+""

Réponses:


516

comme ça:

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

En fait, même si je le fais généralement comme ça pour plus de commodité, sur plus de 1 000 itérations, il semble que la vitesse brute présente un avantage pour.toString()

Voir les tests de performance ici (pas par moi, mais trouvés quand je suis allé écrire le mien): http://jsben.ch/#/ghQYR

Le plus rapide basé sur le test JSPerf ci-dessus: str = num.toString();

Il convient de noter que la différence de vitesse n'est pas trop importante si l'on considère qu'elle peut effectuer la conversion de quelque manière que ce soit 1 million de fois en 0,1 seconde .

Mise à jour: la vitesse semble différer considérablement selon le navigateur. Dans Chrome num + ''semble être le plus rapide basé sur ce test http://jsben.ch/#/ghQYR

Mise à jour 2: Encore une fois sur la base de mon test ci-dessus, il convient de noter que Firefox 20.0.1 exécute .toString()environ 100 fois plus lentement que l' '' + numéchantillon.


58
Il y a des cas où la conversion peut ne pas retourner une réponse préférable: '' + 123e-50retourne "1.23e-48".
hongymagic

21
@hongymagic: cette réponse est en fait la seule concevable: le nombre ne se soucie pas ni ne sait comment il a été entré, et la représentation imprimée standard est avec exactement un chiffre avant le point.
Svante

4
J'ai effectué le test sur jsben.ch/ghQYR , chaque fois qu'il me montre un résultat différent!
Maryam Saeidi

2
J'aime cette réponse car un null foone renvoie pas d'erreur.
ttugates

2
@MaryamSaeidi: L' utilisation du test jsperf.com de drublic ci-dessus semble plus cohérente.
Giraldi

364

À mon avis, n.toString()prend le prix pour sa clarté, et je ne pense pas qu'il entraîne des frais généraux supplémentaires.


Il comporte des frais généraux, même s'il est insignifiant dans les versions récentes du navigateur. Dans Firefox Quantum au moins
peterchaula

11
C'est dangereux. n peut être nul ou non défini.
david.pfx

20
@ david.pfx la question demande comment convertir des valeurs numériques en une chaîne. Fournir des exemples de valeurs non numériques (par exemple null, undefined) qui ne fonctionnent pas avec cette réponse la rend à peine «dangereuse».
Michael Martin-Smucker

5
@ MichaelMartin-Smucker: Si vous écrivez beaucoup de JS, vous vous rendez compte que les choses sont rarement aussi coupées et séchées. La question était ouverte et l'OMI une bonne réponse devrait au moins reconnaître le problème d'une chaîne qui est en fait nulle ou non définie. YMMV.
david.pfx

@ david.pfx J'ai écrit BEAUCOUP de js et je ne me souviens pas de la dernière fois où j'avais besoin d'un nombre sous forme de chaîne et tout sauf un nombre sous forme de chaîne aurait suffi. Ceci est la bonne réponse. Il n'y a pas de réponse au traitement nullou undefinedcar il est spécifique à l'application, alors que j'imagine que (n || defaultNumber).toString() c'est ce que la plupart des gens voudraient dans une telle situation, je suis fortement en désaccord que nous devrions l'intégrer dans toutes les questions. Il s'agissait de convertir des nombres en chaînes, une bonne architecture et d'autres conversions de type si nécessaire sont des leçons séparées.
George Reith

73

Les conversions explicites sont très claires pour quelqu'un qui est nouveau dans la langue. L'utilisation de la coercition de type, comme d'autres l'ont suggéré, conduit à une ambiguïté si un développeur n'est pas au courant des règles de coercition. En fin de compte, le temps de développement est plus coûteux que le temps CPU, donc j'optimiserais pour le premier au détriment du second. Cela étant dit, dans ce cas, la différence est probablement négligeable, mais sinon je suis sûr qu'il existe des compresseurs JavaScript décents qui optimiseront ce genre de chose.

Donc, pour les raisons ci-dessus, j'irais avec: n.toString()ou String(n). String(n)est probablement un meilleur choix car il n'échouera pas s'il nest nul ou non défini.


12
La question portait sur la conversion des nombres, pas sur la conversion des nombres, ou null, ou undefined. Si nc'est nullou en undefinedraison d'un bogue dans mon programme, je préférerais que mon programme échoue dans cet état, pour me donner une meilleure chance de trouver et de corriger le bogue. Les plantages de programmes sont des cadeaux pour le programmeur, pour l'aider à trouver les bugs :-). L'alternative est de fournir un logiciel qui ne fonctionne pas comme prévu, après avoir soigneusement ignoré les bogues. Donc, je ne suis pas fan de l'utilisation String(n)pour masquer une erreur.
Matt Wallis

1
String(n)est bon pour une utilisation dans un style fonctionnel, par exemple avec la combinaison de soulignement _.compose(funcThatNeedsAStringParam, String).
Rik Martins

2
La chaîne (null) ne plantera pas le programme, mais elle renverra la chaîne littérale "null", ce qui n'est probablement pas ce que vous voulez. Si les données peuvent légitimement être nulles, vous devez les traiter explicitement.
Peter Smartt

1
@MattWallis Je pense que cela devrait être la décision du développeur, pas du répondeur, vous ne pensez pas?
forresthopkinsa

31

... L'analyseur JavaScript tente d'analyser la notation par points sur un nombre comme un littéral à virgule flottante.

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

La source


17

La langue en joue évidemment:

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

Ou dans ES6, vous pouvez simplement utiliser des chaînes de modèle :

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

Si je lance les benchmarks avec des modèles ES6, cela s'avère même parfois plus rapide que la '' + numberméthode. Cela dit, les résultats de ces benchmarks varient beaucoup lors de leur exécution plusieurs fois, donc je ne sais pas s'ils doivent être pris trop au sérieux.
Nico Van Belle

15

D'autres réponses couvraient déjà d'autres options, mais je préfère celle-ci:

s = `${n}`

Court, succinct, déjà utilisé dans de nombreux autres endroits (si vous utilisez une version framework / ES moderne), il est donc fort à parier que tout programmeur le comprendra.

Non pas que cela (généralement) compte beaucoup, mais il semble également être parmi les plus rapides par rapport à d' autres méthodes .


Il est également sûr que n ne soit pas un nombre.
david.pfx

Mais n.toString()alors, n'est-ce pas?
amn

1
@amn s'il l' nest, undefinedil générera une erreur de syntaxe en utilisant.toString()
Jee Mok

Cela ne donne-t-il pas simplement le même résultat que String(n)dans tous les cas? La seule différence est que c'est moins clair.
Bennett McElwee

Et beaucoup plus lent.
Adrian Bartholomew

12

La façon la plus simple de convertir une variable en chaîne consiste à ajouter une chaîne vide à cette variable.

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

2
Notez qu'il doit être à l'intérieur de parens: (5.41 + '')pour utiliser les méthodes String comme .substring()et d'autres
Gjaa

Pourquoi faut-il noter cela?
Adrian Bartholomew

7

Si vous devez formater le résultat en un nombre spécifique de décimales, par exemple pour représenter la devise, vous avez besoin de quelque chose comme la toFixed()méthode.

number.toFixed( [digits] )

digits est le nombre de chiffres à afficher après la décimale.


2
Dangereux sauf si vous savez que c'est un chiffre.
david.pfx

6

J'ai utilisé https://jsperf.com pour créer un cas de test pour les cas suivants:

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

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

Au 24 juillet 2018, les résultats indiquent que number + ''c'est le plus rapide dans Chrome, dans Firefox qui est lié aux littéraux de chaîne de modèle.

Les deux String(number), et number.toString()sont environ 95% plus lents que l'option la plus rapide.

tests de performance, description ci-dessus


2

J'aime les deux premiers car ils sont plus faciles à lire. J'ai tendance à utiliser String(n)mais c'est juste une question de style que toute autre chose.

C'est à moins que vous ayez une ligne comme

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

ce qui est très explicite


2

Je pense que cela dépend de la situation mais de toute façon vous pouvez utiliser la .toString()méthode car elle est très claire à comprendre.


2

.toString () est la fonction de transtypage intégrée, je ne suis pas spécialiste de ces détails, mais chaque fois que nous comparons des méthodologies explicites de transtypage de type intégrées, les solutions de contournement intégrées sont toujours préférées.


1

Si je devais tout prendre en considération, je vous proposerais de suivre

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

À mon humble avis, c'est le moyen le plus rapide de convertir en chaîne. Corrigez-moi si je me trompe.


1

La seule solution valable pour presque tous les cas existants et futurs possibles (entrée est nombre, null, non défini, symbole, toute autre chose) est String(x). N'utilisez pas 3 méthodes pour un fonctionnement simple, en vous basant sur des hypothèses de type valeur, comme "ici, je convertis définitivement le nombre en chaîne et ici définitivement le booléen en chaîne".

Explication:

String(x)gère les valeurs nulles, non définies, les symboles, [n'importe quoi] et appelle les .toString()objets.

'' + xappelle .valueOf()x (transtypage en nombre), lance des symboles, peut fournir des résultats dépendants de l'implémentation.

x.toString() jette sur null et indéfini.

Remarque: String(x)échouera toujours sur les objets sans prototype comme Object.create(null).

Si vous n'aimez pas les chaînes comme «Bonjour, non défini» ou si vous souhaitez prendre en charge des objets sans prototype, utilisez la fonction de conversion de type suivante:

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

Avec les littéraux numériques, le point d'accès à une propriété doit être distingué du point décimal. Cela vous laisse les options suivantes si vous souhaitez invoquer String () sur le littéral numérique 123:

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

1

Voici les méthodes pour convertir un entier en chaîne dans JS

Les méthodes sont classées par ordre décroissant de performances.

(Les résultats des tests de performance sont donnés par @DarckBlezzer dans sa réponse)

var num = 1

Méthode 1:

num = `$ {num}`

Méthode 2:

num = num + ''

Méthode 3:

num = chaîne (num)

Méthode 4:

num = num.toString ()

Remarque: vous ne pouvez pas appeler directement tostring () à partir d'un numéro

Par exemple: 2.toString () lancera Uncaught SyntaxError : jeton invalide ou inattendu


0

Si vous êtes curieux de savoir lequel est le plus performant, vérifiez ceci où je compare toutes les différentes conversions Number -> String.

Ressemble 2+''ou 2+""est le plus rapide.

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


0

Nous pouvons également utiliser le constructeur String . Selon cette référence, c'est le moyen le plus rapide de convertir un nombre en chaîne dans Firefox 58, même s'il est plus lent que " + numdans le navigateur populaire Google Chrome.


0

La méthode toFixed()résoudra également le but.

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

0

Vous pouvez appeler Numberobjet, puis appeler toString().

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

Vous pouvez utiliser cette astuce pour un autre objet natif javascript.


0

Je viens de découvrir cela récemment, les méthodes 3 et 4 ne sont pas appropriées car la façon dont les chaînes sont copiées puis assemblées. Pour un petit programme, ce problème est insignifiant, mais pour toute application Web réelle, cette action où nous devons faire face à des manipulations de chaînes de fréquence peut affecter les performances et la lisibilité.

Voici le lien à lire .


0

Je vais rééditer cela avec plus de données quand j'en aurai le temps, car pour l'instant ça va ...

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

production

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

Ouais - test4 est ce que j'utilise régulièrement !!
Adrian Bartholomew

0

Il semble des résultats similaires lors de l'utilisation de node.js. J'ai exécuté ce 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");

et a obtenu les résultats suivants:

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

Des temps similaires chaque fois que je l'ai couru

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.