Javascript tem muitos "truques" em torno de tipos e conversões de tipo, então estou me perguntando se esses 2 métodos são os mesmos ou se há algum caso que os torna diferentes?
fonte
Javascript tem muitos "truques" em torno de tipos e conversões de tipo, então estou me perguntando se esses 2 métodos são os mesmos ou se há algum caso que os torna diferentes?
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 toString
método do objeto passado, por exemplo:
var o = { toString: function () { return "foo"; } };
String(o); // "foo"
Por outro lado, se um identificador se referir a null
ou undefined
, você não puder usar o toString
método, ele apresentará uma TypeError
exceção :
var value = null;
String(null); // "null"
value.toString(); // TypeError
O String
construtor 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:
toString
método.
result
for um primitivo , retorne result
, caso contrário, vá para a Etapa 2.valueOf
método.
result
for 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 ToPrimitive
e as ToString
operações internas.
Também recomendo a leitura deste artigo:
new String(value)
em qualquer valor, ele sempre retornará um objeto string.new String({toString: null})
joga aTypeError
.String()
e+ ''
agora temos uma diferença bastante significativa.String(Symbol())
irá executar, masSymbol() + ''
irá lançar um erro (e Symbol () irá passar por um guarda falsey, ao contrário de null e undefined, entãox && (x + '')
agora pode lançar).value.toString()
causará um erro sevalue
for nulo.String(value)
não deveria.Por exemplo:
vai falhar porque
value == null
.deve exibir uma mensagem "null" (ou semelhante), mas não travará.
fonte
String(value)
deve ter o mesmo resultado quevalue.toString()
em todos os casos, exceto para valores sem propriedades comonull
ouundefined
.''+value
produzirá o mesmo resultado.fonte
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:
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)
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 apenas .valueOf () definido?
.valueOf () definido dentro do objeto será chamado se queremos tratar o objeto como uma string ou como um número
fonte