Transmitindo para string em JavaScript

184

Encontrei três maneiras de converter uma variável Stringno JavaScript.
Procurei essas três opções no código-fonte do jQuery e todas elas estão em uso .
Gostaria de saber se existem diferenças entre eles:

value.toString()
String(value)
value + ""

DEMO

Todos eles produzem a mesma saída, mas um deles é melhor que os outros?
Eu diria que + ""tem a vantagem de salvar alguns personagens, mas essa não é a grande vantagem, mais alguma coisa?

gdoron está apoiando Monica
fonte
1
Parece-me que, se todas as coisas forem iguais, o padrão toString()seria o caminho a seguir.
asawyer
1
@asawyer. E por que isto? Se todos produzirem a mesma saída e fizerem o mesmo, escolha uma e siga em frente. Esta é a minha opinião, se este é realmente o caso aqui .
Gdoron está apoiando Monica
1
Os dois primeiros métodos devem ser equivalentes (você deve verificar o padrão, mas o construtor chamará toString). O terceiro normalmente produz a mesma saída, mas envolve um mecanismo muito diferente (além da velocidade, envolve chamadas diferentes, portanto pode não ser o que você espera para todo tipo de objeto).
Adriano Repetti
6
Na minha opinião, toStringé semanticamente a maneira mais clara de auto-documentar o fato de que você está tentando obter uma string equivalente a um objeto. String(...)é um pouco obtuso, e value + ""é um pouco de hack. Ele também oferece a capacidade de substituir o padrão toStringpor uma implementação personalizada, se você precisar, suponho, como um benefício secundário menor.
asawyer
2
@Adriano. Mas + ""é o mais rápido de acordo com o jsperf, então ... faz de outra maneira, eu acho.
gdoron está apoiando Monica

Respostas:

213

Eles se comportam de maneira diferente quando valueestão null.

  • null.toString()gera um erro - Não é possível chamar o método 'toString' de null
  • String(null)retorna - "nulo"
  • null + ""também retorna - "null"

Um comportamento muito semelhante acontece se valuefor undefined(consulte a resposta de jbabey ).

Fora isso, há uma diferença insignificante de desempenho, que, a menos que você os esteja usando em loops enormes, não vale a pena se preocupar.

Connell
fonte
Esta é realmente uma diferença interessante. Portanto, você deve evitar o uso toString()quando ainda não tiver verificado null.
Sammy S.
@SammyS. Não sei se a impressão nullou undefinedpara a tela é um comportamento mais desejável, em seguida, um erro de javascript ...
Justus Romijn
@JustusRomijn: É verdade mesmo. Enquanto isso, comecei a usar o tipo de opção para lidar com esses erros.
Sammy S.
você pode verificar qualquer uma dessas variáveis ​​fundidas com typeof para verificar a sequência. typeof (null + '') == 'string'
Bruce Lim
4
Há outro caso em que eles se comportam de maneira diferente. v + ''retorna resultado incorreto se v tiver os métodos toString () e valueOf (). A concatenação ignorará toString () e usará valueOf (). Exemplo de uma classe para a qual a concatenação falha: github.com/processing-js/processing-js/blob/…
Mikita Belahlazau
26

Existem diferenças, mas elas provavelmente não são relevantes para sua pergunta. Por exemplo, o protótipo toString não existe em variáveis ​​indefinidas, mas você pode converter indefinido em uma string usando os outros dois métodos:

var foo;

var myString1 = String(foo); // "undefined" as a string

var myString2 = foo + ''; // "undefined" as a string

var myString3 = foo.toString(); // throws an exception

http://jsfiddle.net/f8YwA/

jbabey
fonte
3
Se uma variável não estiver definida, você ainda receberá um erro String(). Exemplo: String(test);lança Uncaught ReferenceError: test is not defined, enquanto var test; String(test);resultará em "undefined".
Anthony
17

Eles se comportam da mesma forma, mas toStringtambém fornecem uma maneira de converter um número de cadeias binárias, octais ou hexadecimais:

Exemplo:

var a = (50274).toString(16)  // "c462"
var b = (76).toString(8)      // "114"
var c = (7623).toString(36)   // "5vr"
var d = (100).toString(2)     // "1100100"
Sarfraz
fonte
9

De acordo com este teste JSPerf , eles diferem na velocidade. Mas, a menos que você os use em grandes quantidades, qualquer um deles deve ter um bom desempenho.

Para completar: Como asawyer já mencionado, você também pode usar o .toString()método.

Sammy S.
fonte
2
Isso JSPerf tem o mesmo teste duas vezes, eu editei E o new String()retorna um objeto não umString
gdoron está apoiando Monica
new String()retorna um objeto yes. String(), no entanto, retorna uma sequência, que é a que está em questão.
Connell
2
Isso não é inteiramente verdade. Como você pode ver nos resultados, concatenar uma sequência vazia e um objeto não produz o mesmo resultado que concatenar um objeto e uma sequência vazia. Além disso, new String(blarg)fornece um Stringobjeto que você pode chamar toString(). No meu depurador do Chrome, eles efetivamente resultam no mesmo tipo de objeto, exceto na referida diferença.
Sammy S.
@SammyS. Você poderia adicionar exemplos de resultados de desempenho à sua resposta? Atualmente, o link jsperf está inoperante e certamente será novamente nos próximos 5 anos ou mais.
Mxmlnkn
9

Além de tudo o que foi dito acima, deve-se observar que, para um valor definido v:

  • String(v) chamadas v.toString()
  • '' + vchamadas v.valueOf()antes de qualquer outro tipo de conversão

Para que pudéssemos fazer algo como:

var mixin = {
  valueOf:  function () { return false },
  toString: function () { return 'true' }
};
mixin === false;  // false
mixin == false;    // true
'' + mixin;       // "false"
String(mixin)     // "true"

Testado no FF 34.0 e no nó 0.10

Simone C.
fonte
8

se você concorda com nulo, indefinido, NaN, 0 e falso, toda a conversão para '' (s ? s+'' : '')é mais rápida.

consulte http://jsperf.com/cast-to-string/8

observação - há diferenças significativas entre os navegadores no momento.

jldec
fonte
4

Exemplo do mundo real: Eu tenho uma função de log que pode ser chamado com um número arbitrário de parâmetros: log("foo is {} and bar is {}", param1, param2). Se um DEBUGsinalizador estiver definido como true, os colchetes serão substituídos pelos parâmetros fornecidos e a cadeia de caracteres será passada para console.log(msg). Os parâmetros podem e serão Strings, Numbers e tudo o que pode ser retornado por chamadas JSON / AJAX, talvez até null.

  • arguments[i].toString()não é uma opção, devido aos nullvalores possíveis (consulte a resposta de Connell Watkins)
  • JSLint vai reclamar arguments[i] + "". Isso pode ou não influenciar uma decisão sobre o que usar. Algumas pessoas aderem estritamente ao JSLint.
  • Em alguns navegadores, concatenar cadeias vazias é um pouco mais rápido do que usar a função ou o construtor de cadeias (consulte Teste JSPerf na resposta Sammys S.) No Opera 12 e Firefox 19, concatenar cadeias vazias é rediculamente mais rápido (95% no Firefox 19) - ou pelo menos o JSPerf diz isso.
Jack
fonte
1

Nesta página, você pode testar o desempenho de cada método você mesmo :)

http://jsperf.com/cast-to-string/2

aqui, em todas as máquinas e navegadores, ' "" + str ' é o mais rápido, (String) str é o mais lento

itinance
fonte