views:

641

answers:

4

i see a few code project solutions:

but wanted to see if there was a regular implementation in javascript?

+5  A: 

No, there is no built-in support for building strings, you have to use concatenation instead.

You can, of course, make an array of different parts of your string and then call join() on that array, but it then depends on how the join is implemented in JS interpreter you are using.

EDIT. I made an experiment to compare the speed of str1+str2 method versus array.push(str1, str2).join() method. The code was simple:

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));

I tested it in IE8 and FireFox 3.5.5, both on a Windows 7 x64.

In the beginning I tested on small number of iterations (some hundred, some thousand items). The results were unpredictable (sometimes string concatenation took 0 milliseconds, sometimes it took 16 milliseconds, the same for array joining).

When I increased the count to 50'000, the results were different in different browsers - in IE the string concatenation was faster (94 milliseconds) and join was slower(125 milliseconds), while in Firefox the array join was faster (113 milliseconds) than string joining (117 milliseconds).

Then I increased the count to 500'000. Now the array.join() was slower than string concatenation in both browsers: string concat 937ms in IE, 1155 ms in Firefox, array join 1265 in IE, 1207 in Firefox.

Maximum iteration count I could test in IE without having "the script is taking too long to execute" was 850'000. Then IE was 1593 for string concatenation and 2046 for array join, Firefox had 2101 for string concatenation and 2249 for array join.

Results - if the number of iterations is small, you can try to use array.join(), as it might be faster in Firefox. When the number increases, the string1+string2 method is faster.

UPDATE
I performed the test on IE6 (WindowsXP). The process stopped to respond immediately and never ended, if I tried the test on more than 100'000 iterations. On 40'000 iterations the results were

Time (strings): 59175 ms
Time (arrays): 220 ms

This means - if you need to support IE6, choose array.join() which is way faster than string concatenation.

naivists
`join()` is part of ECMAScript and afaik every JavaScript interpreter implements it. Why would it "depend"?
Eli Grey
he meant HOW it was implemented... if it's implemented in a way that, in a loop, the string is continually appended opposed to created all at once, then using join would be pointless
John
Yes, it was what I actually meant. Pardon my English ;-)I added results of a comparison how fast which method works in two browsers. You can see, it is different.
naivists
IE6, as always, is the exception :)
Gordon Tucker
thanks for the Excellent tip :)
Ramesh Vel
A: 

There is no built in type for StringBuilder but that code looks quite reasonable

AutomatedTester
+12  A: 

If you have to write code for Internet Explorer make sure you chose an implementation, which uses array joins. Concatenating strings with the + or += operator are extremely slow on IE. This is especially true for IE6. On modern browsers += is usually just as fast as array joins.

When I have to do lots of string concatenations I usually fill an array and don't use a string builder class:

var html = [];
html.push(
  "<html>",
  "<body>",
  "bla bla bla",
  "</body>",
  "</html>"
);
return html.join("");

Note that the push methods accepts multiple arguments.

Fabian Jakobs
+1 for idiom in favor of objects.
slebetman
And if you're generating output inline, or all members are literals, `[foo(), "bar", "baz"].join("");` works, too.
Anonymous
Keep in mind that this is *not* faster than simple concatenation for only a few strings. For example, see: http://dl.dropbox.com/u/360937/join-vs-concat.png
Dave Ward
+3  A: 

That code looks like the route you want to take with a few changes.

You'll want to change the append method to look like this. I've changed it to accept the number 0, and to make it return this so you can chain your appends.

StringBuilder.prototype.append = function (value) {
    if (value || value === 0) {
        this.strings.push(value);
    }
    return this;
}
Gordon Tucker
Why only accept non-NaN numbers and non-empty strings? Your method won't accept `null`, `false`, empty strings, `undefined`, or `NaN`.
Eli Grey
+1 for chaining.
slebetman
@Elijah - I prefer to keep my StringBuilder class clean by not accepting anything but valid strings and numbers. It is just a personal preference.
Gordon Tucker