Antworten:
Sie sind nicht vollständig identisch, und tatsächlich ruft der als Funktion aufgerufene String-Konstruktor (Ihr erstes Beispiel) am Ende die toStringMethode des übergebenen Objekts auf, zum Beispiel:
var o = { toString: function () { return "foo"; } };
String(o); // "foo"
Wenn sich ein Bezeichner hingegen auf nulloder bezieht undefinedund Sie die toStringMethode nicht verwenden können , gibt es eine TypeErrorAusnahme :
var value = null;
String(null); // "null"
value.toString(); // TypeError
Der Stringals Funktion aufgerufene Konstruktor entspricht in etwa:
value + '';
Die Typkonvertierungsregeln von Object- to- Primitive werden in der Spezifikation, der [[DefaultValue]]internen Operation, ausführlich beschrieben .
Kurz zusammengefasst werden beim Konvertieren von Object- to- String die folgenden Schritte ausgeführt:
toStringMethode aus.
resultein Grundelement ist , kehren Sie zurück result, andernfalls fahren Sie mit Schritt 2 fort.valueOfMethode aus.
resultein Grundelement ist , kehren Sie zurück result, andernfalls fahren Sie mit Schritt 3 fort.TypeError.In Anbetracht der obigen Regeln können wir ein Beispiel für die Semantik geben:
var o = {
toString: function () { return "foo"; },
valueOf: function () { return "bar"; }
};
String(o); // "foo"
// Make the toString method unavailable:
o.toString = null;
String(o); // "bar"
// Also make the valueOf method unavailable:
o.valueOf = null;
try {
String(o);
} catch (e) {
alert(e); // TypeError
}
Wenn Sie mehr über diesen Mechanismus erfahren möchten, würde ich empfehlen, sich die ToPrimitiveund die ToStringinternen Operationen anzusehen.
Ich empfehle auch, diesen Artikel zu lesen:
new String({toString: null})wirft a TypeError.
String()und haben + ''jetzt einen ziemlich signifikanten Unterschied. String(Symbol())wird ausgeführt, aber Symbol() + ''wird einen Fehler auslösen (und Symbol () wird im Gegensatz zu null und undefiniert einen Falsey Guard passieren, x && (x + '')kann also jetzt werfen).
value.toString()wird einen Fehler verursachen, wenn valuenull ist. String(value)sollte nicht.
Beispielsweise:
var value = null;
alert(value.toString());
wird scheitern, weil value == null.
var value = null;
alert(String(value));
sollte eine Meldung mit der Aufschrift "null" (oder ähnlich) anzeigen, die jedoch nicht abstürzt.
String(value)sollte das gleiche Ergebnis wie value.toString()in jedem Fall haben, außer für Werte ohne Eigenschaften wie nulloder undefined. ''+valuewird das gleiche Ergebnis produzieren.
String () [der Konstruktoraufruf ] ruft grundsätzlich .toString () auf
.toString () und String () können für primitive Werte (number, boolean, string) aufgerufen werden und bewirken im Grunde nichts Besonderes:
true => 'true'
false => 'false'
17 => '17'
'hallo' => 'hallo'
Beim Aufrufen dieser Funktionen für Objekte wird es jedoch interessant:
Wenn das Objekt über eine eigene .toString () -Funktion verfügt, wird es immer dann aufgerufen, wenn dieses Objekt (explizit / implizit) als Zeichenfolge behandelt werden soll.
let obj = {
myName:"some object",
toString:function(){ return this.myName; }
}
//implicitly treating this obj as a string
"hello " + obj; //"hello some object"
//OR (explicitly)
"hello " + String(obj) //calling the existent toString function
//OR
"hello " + obj.toString(); //calling toString directly
Übrigens, wenn Sie dieses Objekt als Zahl behandeln möchten, sollte darin eine .valueOf () -Funktion definiert sein.
Was ist, wenn wir beide in einem Objekt haben?
wenn wir dieses Objekt als String behandeln wollen => benutze .toString ()
wenn wir dieses Objekt als Zahl behandeln wollen => benutze .valueOf ()
Was ist, wenn wir nur .valueOf () definiert haben?
.valueOf (), das im Objekt definiert ist, wird aufgerufen, unabhängig davon, ob das Objekt als Zeichenfolge oder als Zahl behandelt werden soll
new String(value)jedem Wert wird immer ein Zeichenfolgenobjekt zurückgegeben.