Wie konvertiere ich eine Zahl am besten in eine Zeichenfolge in JavaScript?


517

Was ist der "beste" Weg, um eine Zahl in eine Zeichenfolge umzuwandeln (in Bezug auf Geschwindigkeitsvorteil, Klarheitsvorteil, Speichervorteil usw.)?

Einige Beispiele:

  1. String(n)

  2. n.toString()

  3. ""+n

  4. n+""

Antworten:


516

so was:

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

Obwohl ich es normalerweise aus Bequemlichkeitsgründen normalerweise so mache, scheint es für mehr als 1.000 Iterationen einen Vorteil zu geben.toString()

Siehe Leistungstests hier (nicht von mir, aber gefunden, als ich meine eigenen schrieb): http://jsben.ch/#/ghQYR

Am schnellsten basierend auf dem obigen JSPerf-Test: str = num.toString();

Es sollte beachtet werden, dass der Geschwindigkeitsunterschied nicht übermäßig signifikant ist, wenn man bedenkt, dass die Konvertierung 1 Million Mal in 0,1 Sekunden durchgeführt werden kann .

Update: Die Geschwindigkeit scheint sich je nach Browser stark zu unterscheiden. In Chrome num + ''scheint basierend auf diesem Test http://jsben.ch/#/ghQYR am schnellsten zu sein

Update 2: Wiederum basierend auf meinem obigen Test sollte beachtet werden, dass Firefox 20.0.1 das .toString()ungefähr 100-mal langsamer als das '' + numBeispiel ausführt .


58
Es gibt Fälle, in denen die Konvertierung möglicherweise keine bevorzugte Antwort '' + 123e-50zurückgibt : Rückgabe "1.23e-48".
Hongymagic

21
@hongymagic: Diese Antwort ist in der Tat die einzig denkbare: Die Nummer kümmert sich nicht darum und weiß nicht, wie sie eingegeben wurde, und die gedruckte Standarddarstellung befindet sich mit genau einer Ziffer vor dem Punkt.
Svante

4
Ich habe den Test in jsben.ch/ghQYR ausgeführt , jedes Mal, wenn er mir ein anderes Ergebnis zeigt!
Maryam Saeidi

2
Ich mag diese Antwort, weil a null fookeinen Fehler auslöst.
ttugates

2
@MaryamSaeidi: Mit Drublic ‚s jsperf.com Test scheint über konsistenten.
Giraldi

364

Meiner Meinung nach n.toString()wird der Preis für seine Klarheit vergeben, und ich glaube nicht, dass er zusätzlichen Aufwand mit sich bringt.


Es ist mit einem gewissen Overhead verbunden, obwohl es in neueren Browserversionen unbedeutend ist. In Firefox Quantum mindestens
Peterchaula

11
Das ist unsicher. n kann null oder undefiniert sein.
david.pfx

20
@ david.pfx In der Frage wird gefragt, wie numerische Werte in eine Zeichenfolge konvertiert werden sollen. Die Bereitstellung Beispiele für nicht-numerische Werte (zB null, undefined), die nicht über kaum mit dieser Antwort arbeiten macht es „unsicher“.
Michael Martin-Smucker

5
@ MichaelMartin-Smucker: Wenn du viel JS schreibst, merkst du, dass die Dinge selten so geschnitten und getrocknet sind. Die Frage war offen und IMO sollte eine gute Antwort zumindest das Problem einer Zeichenfolge anerkennen, die tatsächlich null oder undefiniert ist. YMMV.
david.pfx

@ david.pfx Ich habe eine Menge js geschrieben und erinnere mich nicht an das letzte Mal, als ich eine Zahl als Zeichenfolge brauchte und alles andere als eine Zahl als Zeichenfolge ausgereicht hätte. Dies ist die richtige Antwort. Es gibt keine Antwort auf die Handhabung nulloder undefinedda es anwendungsspezifisch ist, obwohl ich mir vorstelle, dass dies das (n || defaultNumber).toString() ist, was die meisten Menschen in einer solchen Situation wollen würden. Ich bin nicht der Meinung, dass wir es in alle Fragen einarbeiten sollten. Hier ging es darum, Zahlen in Zeichenfolgen umzuwandeln, eine gute Architektur und andere Typkonvertierungen, bei denen separate Lektionen erforderlich sind.
George Reith

73

Explizite Konvertierungen sind für jemanden, der neu in der Sprache ist, sehr klar. Die Verwendung von Typenzwang führt, wie andere vorgeschlagen haben, zu Mehrdeutigkeiten, wenn ein Entwickler die Zwangsregeln nicht kennt. Letztendlich ist die Entwicklerzeit teurer als die CPU-Zeit, daher würde ich auf Kosten der letzteren für die erstere optimieren. Abgesehen davon ist der Unterschied in diesem Fall wahrscheinlich vernachlässigbar, aber wenn nicht, bin ich mir sicher, dass es einige anständige JavaScript-Kompressoren gibt, die diese Art von Dingen optimieren.

Aus den oben genannten Gründen würde ich gehen mit: n.toString()oder String(n). String(n)ist wahrscheinlich eine bessere Wahl, da es nicht fehlschlägt, wenn nes null oder undefiniert ist.


12
Die Frage betraf das Konvertieren von Zahlen, nicht das Konvertieren von Zahlen oder nulloder undefined. Wenn nes sich um einen Fehler in meinem Programm handelt nulloder darauf undefinedzurückzuführen ist, würde ich es vorziehen, wenn mein Programm in diesem Zustand fehlschlägt, um mir eine bessere Chance zu geben, den Fehler zu finden und zu beheben. Programmabstürze sind Geschenke an die Programmiererin, um ihr zu helfen, die Fehler zu finden :-). Die Alternative besteht darin, Software bereitzustellen, die nicht wie geplant funktioniert, nachdem die Fehler sorgfältig beschönigt wurden. Ich bin also kein Fan davon String(n), einen Fehler zu maskieren.
Matt Wallis

1
String(n)eignet sich gut für die Verwendung in einem funktionalen Stil, z. B. mit dem Unterstrich-Mähdrescher _.compose(funcThatNeedsAStringParam, String).
Rik Martins

2
String (null) stürzt das Programm nicht ab, gibt jedoch den Literal-String "null" zurück, was wahrscheinlich nicht das ist, was Sie wollen. Wenn die Daten zu Recht null sein könnten, müssen Sie sie explizit behandeln.
Peter Smartt

1
@MattWallis Ich denke, das sollte die Entscheidung des Entwicklers sein, nicht des Antwortenden, meinst du nicht auch?
Forresthopkinsa

30

... Der Parser von JavaScript versucht, die Punktnotation einer Zahl als Gleitkomma-Literal zu analysieren.

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

Quelle


17

Zunge in der Wange offensichtlich:

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

Oder in ES6 können Sie einfach Vorlagenzeichenfolgen verwenden :

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

Wenn ich die Benchmarks mit ES6-Vorlagen ausführe, erweist es sich manchmal sogar als schneller als die '' + numberMethode. Die Ergebnisse dieser Benchmarks variieren jedoch stark, wenn sie mehrmals durchgeführt werden. Sie sind sich also nicht sicher, ob sie zu ernst genommen werden sollten.
Nico Van Belle

15

Andere Antworten deckten bereits andere Optionen ab, aber ich bevorzuge diese:

s = `${n}`

Kurz, prägnant, bereits an vielen anderen Stellen verwendet (wenn Sie ein modernes Framework / eine moderne ES-Version verwenden), sodass jeder Programmierer dies sicher verstehen wird.

Nicht, dass es (normalerweise) viel ausmacht, aber es scheint auch im Vergleich zu anderen Methoden zu den schnellsten zu gehören .


Es ist auch sicher, wenn n keine Zahl ist.
david.pfx

Aber ist n.toString()es nicht so?
Amn

1
@amn wenn es nist undefined, wird es einen Syntaxfehler mit.toString()
Jee Mok

Ergibt dies nicht das gleiche Ergebnis wie String(n)in allen Fällen? Der einzige Unterschied ist, dass es weniger klar ist.
Bennett McElwee

Und viel langsamer.
Adrian Bartholomew

12

Die einfachste Möglichkeit, eine Variable in eine Zeichenfolge zu konvertieren, besteht darin, dieser Variablen eine leere Zeichenfolge hinzuzufügen.

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

2
Beachten Sie, dass es innerhalb von Parens sein muss: (5.41 + '')um die String-Methoden wie .substring()und andere zu verwenden
Gjaa

Warum muss das beachtet werden?
Adrian Bartholomew

7

Wenn Sie das Ergebnis auf eine bestimmte Anzahl von Dezimalstellen formatieren müssen , um beispielsweise die Währung darzustellen, benötigen Sie so etwas wie die toFixed()Methode.

number.toFixed( [digits] )

digits ist die Anzahl der Stellen, die nach der Dezimalstelle angezeigt werden sollen.


2
Unsicher, es sei denn, Sie wissen, dass es sich um eine Nummer handelt.
david.pfx


2

Ich mag die ersten beiden, da sie leichter zu lesen sind. Ich neige dazu zu benutzen, String(n)aber es ist nur eine Frage des Stils als alles andere.

Es sei denn, Sie haben eine Zeile als

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

Das ist sehr selbsterklärend


2

Ich denke, es hängt von der Situation ab, aber trotzdem können Sie die .toString()Methode verwenden, da es sehr klar zu verstehen ist.


2

.toString () ist die integrierte Typumwandlungsfunktion. Ich bin kein Experte für diese Details, aber wenn wir integrierte Typumwandlungsverse mit expliziten Methoden vergleichen, werden integrierte Problemumgehungen immer bevorzugt.


1

Wenn ich alles berücksichtigen müsste, würde ich vorschlagen, folgendes zu tun

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

IMHO, es ist der schnellste Weg, um in String zu konvertieren. Korrigieren Sie mich, wenn ich falsch liege.


1

Die einzig gültige Lösung für fast alle möglichen bestehenden und zukünftigen Fälle (Eingabe ist Zahl, Null, undefiniert, Symbol, alles andere) ist String(x). Verwenden Sie keine 3 Möglichkeiten für eine einfache Operation, basierend auf Annahmen vom Werttyp, wie "hier konvertiere ich definitiv Zahl in Zeichenfolge und hier definitiv Boolesch in Zeichenfolge".

Erläuterung:

String(x)behandelt Nullen, undefiniert, Symbole, [alles] und ruft .toString()nach Objekten.

'' + xAufrufe .valueOf()von x (Umwandlung in eine Zahl), Auslösen von Symbolen, können implementierungsabhängige Ergebnisse liefern.

x.toString() wirft auf Nullen und undefiniert.

Hinweis: String(x)schlägt bei prototyplosen Objekten wie z Object.create(null).

Wenn Sie Zeichenfolgen wie "Hallo, undefiniert" nicht mögen oder prototyplose Objekte unterstützen möchten, verwenden Sie die folgende Typkonvertierungsfunktion:

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

Bei Zahlenliteralen muss der Punkt für den Zugriff auf eine Eigenschaft vom Dezimalpunkt unterschieden werden. Damit haben Sie die folgenden Optionen, wenn Sie String () für das Zahlenliteral 123 aufrufen möchten:

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

1

Im Folgenden finden Sie die Methoden zum Konvertieren einer Ganzzahl in einen String in JS

Die Methoden sind in absteigender Reihenfolge der Leistung angeordnet.

(Die Ergebnisse der Leistungstests werden von @DarckBlezzer in seiner Antwort angegeben.)

var num = 1

Methode 1:

num = `$ {num}`

Methode 2:

num = num + ''

Methode 3:

num = String (num)

Methode 4:

num = num.toString ()

Hinweis: Sie können tostring () nicht direkt von einer Nummer aus aufrufen

Beispiel: 2.toString () löst Uncaught SyntaxError : Ungültiges oder unerwartetes Token aus


0

Wenn Sie neugierig sind, welches das leistungsstärkste ist, sehen Sie sich das an, wo ich die verschiedenen Number -> String-Konvertierungen vergleiche.

Sieht aus wie 2+''oder 2+""sind die schnellsten.

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


0

Wir können auch den String- Konstruktor verwenden. Laut diesem Benchmark ist dies der schnellste Weg, eine Zahl in Firefox 58 in einen String zu konvertieren, obwohl sie langsamer ist als " + numim beliebten Browser Google Chrome.


0

Methode toFixed()löst auch den Zweck.

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

0

Sie können NumberObjekt aufrufen und dann aufrufen toString().

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

Sie können diesen Trick für andere native Javascript-Objekte verwenden.


0

Kommen Sie erst kürzlich darauf, Methode 3 und 4 sind nicht geeignet, da die Zeichenfolgen kopiert und dann zusammengesetzt werden. Für ein kleines Programm ist dieses Problem unbedeutend, aber für jede echte Webanwendung kann diese Aktion, bei der wir uns mit Manipulationen von Frequenzzeichenfolgen befassen müssen, die Leistung und Lesbarkeit beeinträchtigen.

Hier ist der Link zum Lesen .


0

Ich werde dies mit mehr Daten erneut bearbeiten, wenn ich Zeit dazu habe, denn im Moment ist das in Ordnung ...

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

Ausgabe

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 benutze ich regelmäßig !!
Adrian Bartholomew

0

Es scheint ähnliche Ergebnisse bei der Verwendung von node.js. Ich habe dieses Skript ausgeführt:

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

und bekam die folgenden Ergebnisse:

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

Ähnliche Zeiten jedes Mal, wenn ich es lief.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.