Odpowiedzi:
Nie są one całkowicie takie same, a właściwie konstruktor String wywołany jako funkcja (Twój pierwszy przykład) na końcu wywoła toStringmetodę przekazanego obiektu, na przykład:
var o = { toString: function () { return "foo"; } };
String(o); // "foo"
Z drugiej strony, jeśli identyfikator odnosi się do metody nulllub undefinednie możesz jej użyć toString, będzie to TypeErrorwyjątek :
var value = null;
String(null); // "null"
value.toString(); // TypeError
StringKonstruktor nazywa się funkcją byłaby grubsza odpowiada:
value + '';
Reguły konwersji typu z Object -to- Primitive są szczegółowo opisane w specyfikacji, czyli [[DefaultValue]]operacji wewnętrznej.
Krótko podsumowane podczas konwersji z klasy Object -to- ciąg , z następujących kroków:
toStringmetodę.
resultjest to prymityw , wróć result, w przeciwnym razie przejdź do kroku 2.valueOfmetodę.
resultjest to prymityw , wróć result, w przeciwnym razie przejdź do kroku 3.TypeError.Biorąc pod uwagę powyższe zasady, możemy podać przykład zastosowanej semantyki:
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
}
Jeśli chcesz dowiedzieć się więcej o tym mechanizmie, polecam przyjrzeć ToPrimitivesię ToStringoperacjom wewnętrznym i.
Polecam również przeczytanie tego artykułu:
new String({toString: null})rzuca TypeError.
String()i + ''teraz mamy dość znaczącą różnicę. String(Symbol())uruchomi się, ale Symbol() + ''zgłosi błąd (a Symbol () przejdzie przez fałszywego strażnika, w przeciwieństwie do wartości null i undefined, więc x && (x + '')może teraz rzucać).
value.toString()spowoduje błąd, jeśli valuejest null. String(value)nie powinieneś.
Na przykład:
var value = null;
alert(value.toString());
nie powiedzie się, ponieważ value == null.
var value = null;
alert(String(value));
powinien wyświetlić komunikat o treści „null” (lub podobny), ale nie ulegnie awarii.
String(value)powinien mieć taki sam wynik jak value.toString()w każdym przypadku, z wyjątkiem wartości bez właściwości, takich jak nulllub undefined. ''+valueprzyniesie ten sam wynik.
String () [ wywołanie konstruktora ] w zasadzie wywołuje metodę .toString ()
.toString () i String () można wywołać na wartościach pierwotnych (number, boolean, string) i zasadniczo nie zrobią nic specjalnego:
true => „prawda”
false => „false”
17 => „17”
'hello' => 'hello'
Ale wywoływanie tych funkcji na obiektach jest tam, gdzie robi się interesujące:
jeśli obiekt ma własną funkcję .toString (), zostanie wywołany, gdy kiedykolwiek będziesz potrzebować traktowania tego obiektu jako ciągu (jawnie / niejawnie)
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
Nawiasem mówiąc, jeśli chcesz traktować ten obiekt jako liczbę, powinien on mieć zdefiniowaną funkcję .valueOf () .
co jeśli mamy oba w jednym obiekcie?
jeśli chcemy traktować ten obiekt jako string => użyj .toString ()
jeśli chcemy traktować ten obiekt jako liczbę => użyj .valueOf ()
co jeśli mamy zdefiniowane tylko .valueOf () ?
.valueOf () zdefiniowana wewnątrz obiektu zostanie wywołana niezależnie od tego, czy chcemy obsługiwać obiekt jako ciąg znaków, czy jako liczbę
new String(value)dla dowolnej wartości, zawsze zwróci obiekt typu string.