32

I'm writing JavaScript unit tests and I need to create a string of length 65536. What's the best way to do this in JavaScript?

Currently I'm using:

var myString = '';
for (var i = 0; i <= 65535; ++i) {
    myString += 'x';
}
Victor Lyuboslavsky
  • 9,882
  • 25
  • 87
  • 134

5 Answers5

77

This is a forward-looking answer, and won't work in current implementations.

ECMAScript 6 is currently defining a String.prototype.repeat method. This will allow you to do:

var result = "x".repeat(65535);

Again, this is a future addition. Currently ECMAScript 6 (Harmony) is being drafted, and this could technically be removed, though it doesn't seem likely.

Current draft:

15.5.4.21 String.prototype.repeat (count)

The following steps are taken:

  1. Let O be CheckObjectCoercible(this value).
  2. Let S be ToString(O).
  3. ReturnIfAbrupt(S).
  4. Let n be the result of calling ToInteger(count).
  5. ReturnIfAbrupt(n).
  6. If n < 0, then throw a RangeError exception.
  7. If n is +Infinity, then throw a RangeError exception.
  8. Let T be a String value that is made from n copies of S appended together. If n is 0, T is the empty String.
  9. Return T.

NOTE 1 This method creates a String consisting of the string elements of this object (converted to String) repeated count time.

NOTE 2 The repeat function is intentionally generic; it does not require that its this value be a String object.Therefore, it can be transferred to other kinds of objects for use as a method.

  • 1
    2015 update: ECMAScript 2015 was finalized and this is in it, so it's definitely safe to use. It's currently supported in Chrome and Firefox, not IE or Safari. MDN has a polyfill available. – twhb Aug 31 '15 at 14:32
55

How about

Array(65537).join('x')

Note, that it's 65537, not 65536, because you put characters inbetween.

aztek
  • 1,399
  • 10
  • 12
10

Array.prototype.join doesn't have to be called on an Array, just an Object with a length property (tested in Google Chrome, FireFox, IE10)

function makeStr(len, char) {
    return Array.prototype.join.call({length: (len || -1) + 1}, char || 'x');
}
makeStr(5); // "xxxxx"

This lets you benefit from native function making the string, without the overhead of a huge array.

Paul S.
  • 64,864
  • 9
  • 122
  • 138
6

Out of interest, I created a quick benchmark test on jsperf.com:

http://jsperf.com/mkstring

Contestants are

  1. Array(x).join()

  2. Array.prototype.join posted by Paul S.

  3. strRepeat from underscore.string

function strRepeat(str, qty) {
  if (qty < 1) return '';
  var result = '';
  while (qty > 0) {
    if (qty & 1) result += str;
    qty >>= 1, str += str;
  }
  return result;
}

strRepeat('*', 20000);
  1. EMCAScript 6 String.repeat mentioned by Crayz Train

For Firefox 34 (which already supports the ECMAScript6 String.repeat), the native repeat is the fastest, followed by strRepeat.

Interestingly with Chrom(e|ium) 39 the strRepeat function is even faster compared to the native String.repeat function of Firefox in my test runs.

For all tested browsers, the function proposed by Paul S. using the native Array.join method is slower than the strRepeat function of the underscore.string library. So, don't use it if you're looking for a fast method.

cbley
  • 4,538
  • 1
  • 17
  • 32
  • Instead of referring to the link, just copy paste the interesting parts of it. – fedorqui Jan 08 '15 at 16:57
  • 1
    OK, I've updated my answer and also the jsperf tests in order to avoid an error for browsers lacking the String.repeat function. – cbley Jan 09 '15 at 12:43
  • I am not very sure about what is this answer supposed to do. In case you are refering to a post or a website, remember what they suggest here: "While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes." – fedorqui Jan 10 '15 at 12:58
  • 1
    @fedorqui The original question was what is the _best_ way to solve the problem. In this context it probably means, what is the _fastest_ way. You can only find that out by comparison. I'm providing a link to the jsperf tests because that's the only reasonable thing to do for such a comparison, as the result will vary depending on your OS, system, browser and CPU/memory load. – cbley Jan 11 '15 at 21:22
  • 1
    This is a very fair point. I believe the rule of thumb for links is: what if the link breaks, will the answer alone be good enough? As I think this is the case, I am upvoting this answer and welcoming you to the community. – fedorqui Jan 12 '15 at 10:30
2

You could create an array of length whatver you want and then use the join() method on the array which will make it into a string. Array(number).join(char) this creates an array on size number -1. Also note that you do not want to use your method because concatenating strings is very expensive(O(n) every concat). I am not sure if javascript has a StringBuilder like java

aaronman
  • 18,343
  • 7
  • 63
  • 78
  • 1
    Just a clarification `Array(number).join(char)` will create an array containing `number - 1` elements. – HBP Jun 02 '13 at 18:05