Respostas:
Eles não são completamente iguais e, na verdade, o construtor String chamado como uma função (seu primeiro exemplo) irá, no final, chamar o toStringmétodo do objeto passado, por exemplo:
var o = { toString: function () { return "foo"; } };
String(o); // "foo"
Por outro lado, se um identificador se referir a nullou undefined, você não puder usar o toStringmétodo, ele apresentará uma TypeErrorexceção :
var value = null;
String(null); // "null"
value.toString(); // TypeError
O Stringconstrutor chamado como uma função seria aproximadamente equivalente a:
value + '';
As regras de conversão de tipo de Objeto- para- Primitivo são descritas detalhadamente na especificação, a [[DefaultValue]]operação interna.
Resumindo resumidamente, ao converter de objeto- para- string , as seguintes etapas são executadas:
toStringmétodo.
resultfor um primitivo , retorne result, caso contrário, vá para a Etapa 2.valueOfmétodo.
resultfor um primitivo , retorne result, caso contrário, vá para a Etapa 3.TypeError.Dadas as regras acima, podemos dar um exemplo da semântica envolvida:
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 você quiser saber mais sobre este mecanismo, eu recomendo olhar para ToPrimitivee as ToStringoperações internas.
Também recomendo a leitura deste artigo:
new String({toString: null})joga a TypeError.
String()e + ''agora temos uma diferença bastante significativa. String(Symbol())irá executar, mas Symbol() + ''irá lançar um erro (e Symbol () irá passar por um guarda falsey, ao contrário de null e undefined, então x && (x + '')agora pode lançar).
value.toString()causará um erro se valuefor nulo. String(value)não deveria.
Por exemplo:
var value = null;
alert(value.toString());
vai falhar porque value == null.
var value = null;
alert(String(value));
deve exibir uma mensagem "null" (ou semelhante), mas não travará.
String(value)deve ter o mesmo resultado que value.toString()em todos os casos, exceto para valores sem propriedades como nullou undefined. ''+valueproduzirá o mesmo resultado.
String () [a chamada do construtor ] está basicamente chamando o .toString ()
.toString () e String () podem ser chamados em valores primitivos (número, booleano, string) e basicamente não farão nada de especial:
verdadeiro => 'verdadeiro'
falso => 'falso'
17 => '17'
'olá' => 'olá'
Mas chamar essas funções em objetos é onde as coisas ficam interessantes:
se o objeto tiver sua própria função .toString (), ele será chamado sempre que você precisar que este objeto seja tratado como uma string (explicitamente / 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 propósito, se você quiser tratar este objeto como um número, ele deve ter uma função .valueOf () definida nele.
e se tivermos ambos em um objeto?
se quisermos tratar este objeto como uma string => use .toString ()
se quisermos tratar este objeto como um número => use .valueOf ()
e se tivermos apenas .valueOf () definido?
.valueOf () definido dentro do objeto será chamado se queremos tratar o objeto como uma string ou como um número
new String(value)em qualquer valor, ele sempre retornará um objeto string.