Qual è la differenza tra String (value) e value.toString ()


105

Javascript ha molti "trucchi" sui tipi e sulle conversioni di tipo, quindi mi chiedo se questi 2 metodi sono gli stessi o se c'è qualche caso d'angolo che li rende diversi?

Risposte:


123

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:

  1. Se disponibile, eseguire il toStringmetodo.
    • Se resultè primitivo , torna indietro result, altrimenti vai al passaggio 2.
  2. Se disponibile, eseguire il valueOfmetodo.
    • Se resultè un primitivo , torna indietro result, altrimenti vai al passaggio 3.
  3. Lancia 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:


1
C'è un terzo "modo", se lo chiami: new String(value)su qualsiasi valore, restituirà sempre un oggetto stringa.
Herbertusz

@Herbertusz new String({toString: null})lancia un file TypeError.
Константин Ван

Con l'aggiunta di simboli 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).
yeerk

24

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.


3
Non ho mai visto un'eccezione di puntatore nullo in javascript ... dove l'hai vista?
Dagg Nabbit

simpatico. sarebbe ancora più bello con un esempio
mykhal

@no, @casablanca risolto. Sono abituato a Java. @mykhal Come ti sembra?
Jonathan

Restituisce una stringa "null" :)
moefinley

1

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.


1

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.