Casting in String in JavaScript

184

Ich habe drei Möglichkeiten gefunden, eine Variable Stringin JavaScript umzuwandeln.
Ich habe im jQuery-Quellcode nach diesen drei Optionen gesucht, und sie werden alle verwendet .
Ich würde gerne wissen, ob es Unterschiede zwischen ihnen gibt:

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

DEMO

Sie alle produzieren die gleiche Leistung, aber ist einer von ihnen besser als die anderen?
Ich würde sagen, das + ""hat den Vorteil, dass es einige Charaktere speichert, aber das ist nicht der große Vorteil, sonst noch etwas?

Gdoron unterstützt Monica
quelle
1
Mir scheint, wenn alle Dinge gleich sind, wäre der Standard toString()der richtige Weg.
Asawyer
1
@asawyer. Und warum ist das? Wenn alle die gleiche Ausgabe produzieren und das Gleiche tun, wählen Sie eine aus und fahren Sie fort. Dies ist meine Meinung, wenn dies hier wirklich der Fall ist .
Gdoron unterstützt Monica
1
Die ersten beiden Methoden sollten äquivalent sein (Sie sollten den Standard überprüfen, aber der Konstruktor ruft toString auf). Der dritte erzeugt normalerweise die gleiche Ausgabe, beinhaltet jedoch einen sehr unterschiedlichen Mechanismus (neben der Geschwindigkeit sind auch unterschiedliche Aufrufe erforderlich, sodass dies möglicherweise nicht für jede Art von Objekt das ist, was Sie erwarten).
Adriano Repetti
6
Meiner Meinung nach toStringist dies semantisch der klarste Weg, um die Tatsache selbst zu dokumentieren, dass Sie versuchen, eine Zeichenfolge zu erhalten, die einem Objekt entspricht. String(...)ist ein wenig stumpf und value + ""ist ein bisschen ein Hack. Es gibt Ihnen auch die Möglichkeit, die Standardeinstellung toStringmit einer benutzerdefinierten Implementierung zu überschreiben , falls Sie dies jemals als geringfügigen Nebeneffekt benötigen.
Asawyer
2
@ Adriano. Aber + ""laut jsperf ist es das schnellste, also ... es macht es auf keine andere Weise, denke ich.
Gdoron unterstützt Monica

Antworten:

212

Sie verhalten sich anders, wenn das valueist null.

  • null.toString()löst einen Fehler aus - Die Methode 'toString' von null kann nicht aufgerufen werden
  • String(null)gibt zurück - "null"
  • null + ""gibt auch zurück - "null"

Sehr ähnliches Verhalten tritt auf, wenn dies der Fallvalue ist undefined(siehe die Antwort von jbabey ).

Abgesehen davon gibt es einen vernachlässigbaren Leistungsunterschied, über den Sie sich keine Sorgen machen sollten, es sei denn, Sie verwenden sie in großen Schleifen.

Connell
quelle
Das ist eigentlich ein interessanter Unterschied. Sie sollten es daher unterlassen, toString()wenn Sie es noch nicht überprüft nullhaben.
Sammy S.
@SammyS. Ich weiß nicht, ob das Drucken nulloder undefineddas Anzeigen auf dem Bildschirm wünschenswerter ist als ein Javascript-Fehler ...
Justus Romijn
@ JustusRomijn: In der Tat wahr. In der Zwischenzeit habe ich begonnen, den Optionstyp zu verwenden, um solche Fehler zu behandeln.
Sammy S.
Sie können jede dieser konvertierten Variablen mit typeof überprüfen, um nach Zeichenfolgen zu suchen. typeof (null + '') == 'string'
Bruce Lim
4
Es gibt einen anderen Fall, in dem sie sich anders verhalten. v + ''Gibt ein falsches Ergebnis zurück, wenn v sowohl die Methoden toString () als auch valueOf () hat. Die Verkettung ignoriert toString () und verwendet valueOf (). Beispiel einer Klasse, für die die Verkettung fehlschlägt: github.com/processing-js/processing-js/blob/…
Mikita Belahlazau
26

Es gibt Unterschiede, aber sie sind wahrscheinlich für Ihre Frage nicht relevant. Beispielsweise ist der toString-Prototyp für undefinierte Variablen nicht vorhanden, aber Sie können undefiniert mit den beiden anderen Methoden in eine Zeichenfolge umwandeln:

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
quelle
3
Wenn eine Variable überhaupt nicht definiert ist, erhalten Sie immer noch einen Fehler für String(). Beispiel: String(test);wirft Uncaught ReferenceError: test is not defined, während var test; String(test);ergibt "undefined".
Anthony
17

Sie verhalten sich gleich, toStringbieten aber auch die Möglichkeit, eine binäre, oktale oder hexadezimale Zahl zu konvertieren:

Beispiel:

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
quelle
9

Nach diesem JSPerf-Test unterscheiden sie sich in der Geschwindigkeit. Aber wenn Sie sie nicht in großen Mengen verwenden, sollte jeder von ihnen eine gute Leistung bringen.

Der Vollständigkeit halber : Wie bereits erwähnt, können Sie die .toString()Methode auch anwenden .

Sammy S.
quelle
2
Das jsperf hat den gleichen Test zweimal, ich habe ihn bearbeitet Und das new String()gibt ein Objekt zurück, das nicht aString
gdoron Monica am
new String()gibt ein Objekt yes zurück. String()Gibt jedoch eine Zeichenfolge zurück, die in der Frage angegeben ist.
Connell
2
Dies ist nicht ganz richtig. Wie Sie den Ergebnissen entnehmen können, führt das Verketten einer leeren Zeichenfolge und eines Objekts nicht zum gleichen Ergebnis wie das Verketten eines Objekts und einer leeren Zeichenfolge. Außerdem erhalten new String(blarg)Sie ein StringObjekt, das Sie aufrufen können toString(). In meinem Chrome-Debugger führen sie mit Ausnahme des Unterschieds effektiv zu derselben Art von Objekt.
Sammy S.
@SammyS. Könnten Sie bitte Ihrer Antwort Beispielleistungsergebnisse hinzufügen? Der jsperf-Link ist derzeit nicht verfügbar und wird sicherlich in den nächsten 5+ Jahren wieder verfügbar sein.
mxmlnkn
9

Zusätzlich zu all dem sollte man beachten, dass für einen definierten Wert v:

  • String(v) Anrufe v.toString()
  • '' + vAnrufe v.valueOf()vor jeder anderen Besetzung

Also könnten wir so etwas machen wie:

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

Getestet in FF 34.0 und Node 0.10

Simone C.
quelle
8

Wenn Sie mit null, undefined, NaN, 0 und false einverstanden sind, ist das Casting auf '' (s ? s+'' : '')schneller.

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

Hinweis - Derzeit gibt es erhebliche Unterschiede zwischen den Browsern.

jldec
quelle
4

Beispiel aus der Praxis: Ich habe eine Protokollfunktion, die mit einer beliebigen Anzahl von Parametern aufgerufen werden kann : log("foo is {} and bar is {}", param1, param2). Wenn ein DEBUGFlag auf gesetzt ist true, werden die Klammern durch die angegebenen Parameter ersetzt und die Zeichenfolge an übergeben console.log(msg). Parameter können und werden Strings, Numbers und alles sein, was von JSON / AJAX-Aufrufen zurückgegeben werden kann, vielleicht sogar null.

  • arguments[i].toString()ist aufgrund möglicher nullWerte keine Option (siehe Antwort von Connell Watkins)
  • JSLint wird sich beschweren arguments[i] + "". Dies kann eine Entscheidung über die Verwendung beeinflussen oder nicht. Einige Leute halten sich strikt an JSLint.
  • In einigen Browsern ist das Verketten leerer Zeichenfolgen etwas schneller als die Verwendung der Zeichenfolgenfunktion oder des Zeichenfolgenkonstruktors (siehe JSPerf-Test in Sammys S. Antwort). In Opera 12 und Firefox 19 ist das Verketten leerer Zeichenfolgen unglaublich schneller (95% in Firefox 19) - oder zumindest JSPerf sagt dies.
Jack
quelle
1

Auf dieser Seite können Sie die Leistung jeder Methode selbst testen :)

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

Hier ist auf allen Computern und Browsern ' "" + str ' der schnellste, (String) str der langsamste

itinance
quelle