Vejo algumas soluções de projeto de código .
Mas existe uma implementação regular em JavaScript?
Vejo algumas soluções de projeto de código .
Mas existe uma implementação regular em JavaScript?
Respostas:
Se você tiver que escrever código para o Internet Explorer, certifique-se de escolher uma implementação, que usa junções de matriz. A concatenação de strings com o operador +
ou +=
é extremamente lenta no IE. Isso é especialmente verdadeiro para o IE6. Em navegadores modernos+=
geralmente é tão rápido quanto as junções de array.
Quando tenho que fazer muitas concatenações de string, geralmente preencho uma matriz e não uso uma classe construtora de string:
var html = [];
html.push(
"<html>",
"<body>",
"bla bla bla",
"</body>",
"</html>"
);
return html.join("");
Observe que os push
métodos aceitam vários argumentos.
[foo(), "bar", "baz"].join("");
funciona também.
push
poderia aceitar vários argumentos. As coisas aleatórias que você aprende.
Acabei de verificar novamente o desempenho em http://jsperf.com/javascript-concat-vs-join/2 . Os casos de teste se concatenam ou unem o alfabeto 1.000 vezes.
Nos navegadores atuais (FF, Opera, IE11, Chrome), "concat" é cerca de 4 a 10 vezes mais rápido do que "join".
No IE8, ambos retornam resultados aproximadamente iguais.
No IE7, "join" é cerca de 100 vezes mais rápido, infelizmente.
Não, não há suporte integrado para a construção de strings. Você deve usar a concatenação.
Você pode, é claro, fazer uma matriz de diferentes partes de sua string e, em seguida, chamar join()
esse array, mas isso depende de como a junção é implementada no interpretador JavaScript que você está usando.
Fiz um experimento para comparar a velocidade do str1+str2
método versus array.push(str1, str2).join()
método. O código era simples:
var iIterations =800000;
var d1 = (new Date()).valueOf();
str1 = "";
for (var i = 0; i<iIterations; i++)
str1 = str1 + Math.random().toString();
var d2 = (new Date()).valueOf();
log("Time (strings): " + (d2-d1));
var d3 = (new Date()).valueOf();
arr1 = [];
for (var i = 0; i<iIterations; i++)
arr1.push(Math.random().toString());
var str2 = arr1.join("");
var d4 = (new Date()).valueOf();
log("Time (arrays): " + (d4-d3));
Eu testei no Internet Explorer 8 e Firefox 3.5.5, ambos em um Windows 7 x64.
No início, testei em um pequeno número de iterações (algumas centenas, alguns milhares de itens). Os resultados eram imprevisíveis (às vezes a concatenação de strings levava 0 milissegundos, às vezes levava 16 milissegundos, o mesmo para a junção da matriz).
Quando aumentei a contagem para 50.000, os resultados foram diferentes em navegadores diferentes - no Internet Explorer a concatenação de strings foi mais rápida (94 milissegundos) e a junção foi mais lenta (125 milissegundos), enquanto no Firefox a junção da matriz foi mais rápida (113 milissegundos) do que junção de string (117 milissegundos).
Então, aumentei a contagem para 500.000. Agora array.join()
era mais lento do que a concatenação de string em ambos os navegadores: a concatenação de string era de 937 ms no Internet Explorer, 1155 ms no Firefox, array join 1265 no Internet Explorer e 1207 ms no Firefox.
A contagem máxima de iterações que pude testar no Internet Explorer sem ter "o script está demorando muito para ser executado" foi 850.000. Então, o Internet Explorer era 1593 para concatenação de string e 2046 para junção de array, e o Firefox tinha 2101 para concatenação de string e 2249 para junção de array.
Resultados - se o número de iterações for pequeno, você pode tentar usararray.join()
, pois pode ser mais rápido no Firefox. Quando o número aumenta, o string1+string2
método é mais rápido.
Realizei o teste no Internet Explorer 6 (Windows XP). O processo parava de responder imediatamente e nunca terminava, se eu tentasse o teste em mais de 100.000 iterações. Em 40.000 iterações, os resultados foram
Time (strings): 59175 ms
Time (arrays): 220 ms
Isso significa - se você precisar oferecer suporte ao Internet Explorer 6, escolha array.join()
qual é mais rápido do que a concatenação de strings.
join()
faz parte do ECMAScript e afaik todo interpretador de JavaScript o implementa. Por que isso "dependeria"?
Esse código se parece com a rota que você deseja seguir, com algumas alterações.
Você vai querer alterar o método append para ficar assim. Eu mudei para aceitar o número 0 e fazê-lo retornar this
para que você possa encadear seus anexos.
StringBuilder.prototype.append = function (value) {
if (value || value === 0) {
this.strings.push(value);
}
return this;
}
null
, false
, cadeias vazias, undefined
ou NaN
.
A versão ECMAScript 6 (também conhecida como ECMAScript 2015) do JavaScript introduziu literais de string .
var classType = "stringbuilder";
var q = `Does JavaScript have a built-in ${classType} class?`;
Observe que back-ticks, em vez de aspas simples, envolvem a string.
Em C # você pode fazer algo como
String.Format("hello {0}, your age is {1}.", "John", 29)
Em JavaScript, você poderia fazer algo como
var x = "hello {0}, your age is {1}";
x = x.replace(/\{0\}/g, "John");
x = x.replace(/\{1\}/g, 29);
{0}
foi substituído contiver {1}
.
Para os interessados, aqui está uma alternativa para invocar Array.join:
var arrayOfStrings = ['foo', 'bar'];
var result = String.concat.apply(null, arrayOfStrings);
console.log(result);
A saída, como esperado, é a string 'foobar'. No Firefox, essa abordagem supera Array.join, mas é superada por + concatenação. Como String.concat requer que cada segmento seja especificado como um argumento separado, o chamador é limitado por qualquer limite de contagem de argumento imposto pelo mecanismo JavaScript em execução. Dê uma olhada na documentação de Function.prototype.apply () para mais informações.
Eu defini esta função:
function format() {
var args = arguments;
if (args.length <= 1) {
return args;
}
var result = args[0];
for (var i = 1; i < args.length; i++) {
result = result.replace(new RegExp("\\{" + (i - 1) + "\\}", "g"), args[i]);
}
return result;
}
E pode ser chamado como c #:
var text = format("hello {0}, your age is {1}.", "John", 29);
Resultado:
Olá John, você tem 29 anos.
Quando me vejo fazendo muita concatenação de strings em JavaScript, começo a procurar modelos. Handlebars.js funciona muito bem mantendo o HTML e o JavaScript mais legíveis. http://handlebarsjs.com
Que tal sys.StringBuilder()
tentar o seguinte artigo.