Risposte:
Non sono completamente uguali, e in realtà, il costruttore String chiamato come funzione (il tuo primo esempio), alla fine chiamerà il toStringmetodo dell'oggetto passato, ad esempio:
var o = { toString: function () { return "foo"; } };
String(o); // "foo"
D'altra parte, se un identificatore si riferisce a nullo undefined, non puoi usare il toStringmetodo, ti darà TypeErrorun'eccezione :
var value = null;
String(null); // "null"
value.toString(); // TypeError
Il Stringcostruttore chiamato come funzione sarebbe più o meno equivalente a:
value + '';
Le regole di conversione del tipo da Object- to- Primitive sono descritte in dettaglio nella specifica, l' [[DefaultValue]]operazione interna.
Riassumendo brevemente, durante la conversione da Object- to- String , vengono eseguiti i seguenti passaggi:
toStringmetodo.
resultè primitivo , torna indietro result, altrimenti vai al passaggio 2.valueOfmetodo.
resultè un primitivo , torna indietro result, altrimenti vai al passaggio 3.TypeError.Date le regole precedenti, possiamo fare un esempio della semantica coinvolta:
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
}
Se vuoi saperne di più su questo meccanismo, ti consiglio di guardare il ToPrimitivee le ToStringoperazioni interne.
Consiglio anche di leggere questo articolo:
new String({toString: null})lancia un file TypeError.
String()e + ''ora hanno una differenza abbastanza significativa. String(Symbol())verrà eseguito, ma Symbol() + ''genererà un errore (e Symbol () passerà una guardia falsa, a differenza di null e undefined, quindi x && (x + '')ora può lanciare).
value.toString()causerà un errore se valueè nullo. String(value)non dovrebbe.
Per esempio:
var value = null;
alert(value.toString());
fallirà perché value == null.
var value = null;
alert(String(value));
dovrebbe visualizzare un messaggio con la scritta "null" (o simile), ma non andrà in crash.
String(value)dovrebbe avere lo stesso risultato value.toString()di tutti i casi, tranne per i valori senza proprietà come nullo undefined. ''+valueprodurrà lo stesso risultato.
String () [la chiamata del costruttore ] sta praticamente chiamando il .toString ()
.toString () e String () possono essere chiamati su valori primitivi (numero, booleano, stringa) e fondamentalmente non faranno nulla di speciale:
true => 'true'
false => 'false'
17 => "17"
'ciao' => 'ciao'
Ma chiamare queste funzioni sugli oggetti è dove le cose si fanno interessanti:
se l'oggetto ha la sua funzione .toString () verrà chiamato ogni volta che avrai bisogno che questo oggetto venga trattato come una stringa (esplicitamente / implicitamente)
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
A proposito, se vuoi trattare questo oggetto come un numero, dovrebbe avere una funzione .valueOf () definita in esso.
cosa succede se abbiamo entrambi in un oggetto?
se vogliamo trattare questo oggetto come una stringa => usa .toString ()
se vogliamo trattare questo oggetto come un numero => usa .valueOf ()
cosa succede se abbiamo definito solo .valueOf () ?
.valueOf () definito all'interno dell'oggetto verrà chiamato se vogliamo gestire l'oggetto come una stringa o come un numero
new String(value)su qualsiasi valore, restituirà sempre un oggetto stringa.