112

So we had a case where we would have an object, where key is id (int) and the value is the string. But we noticed that most of the times, we look up id based on the string, so we decided to reverse it and make a string the key and the value is the id. Because that way instead of going through each item and compare values, we could just do var id = storage[text];. Below are the examples of what we did.

Here's the example of the old implementation:

var storage = {
  0 : null,
  1 : "Hello",
  2 : "world!",
  3 : "How are you?"
}

Here's the example of the new implementation:

var storage = {
  "null" : 0,
  "Hello" : 1,
  "world!" : 2,
  "How are you?" : 3
}

I understand that now the string is the key and it's ok to get the same id for the same strings. But since now the string can be potentially pretty huge (slim chance, but probably max 1KB per string), is there a length limit JS or Android webview puts on the object keys?

And also, does this implementation have disadvantages? I haven't noticed any issues so far, but you never know.

Intervalia
  • 10,248
  • 2
  • 30
  • 60
Sherzod
  • 5,041
  • 10
  • 47
  • 66

3 Answers3

128

I have researched this a bit.

MDN is silent on the issue, and so is the spec (ES5, ES6). They only state that the property accessor must be a string, without any qualifications – in other words, there is no limit as far as the spec is concerned. That's hardly surprising.

How browsers handle it, is another matter. I have set up a test and run it in a number of browsers. Chrome 40 (Desktop), Chrome 40 (Android 5.1), Firefox 36, Opera 27, and IE9+ can deal with a property name of up to 227 characters. Safari 8 (OS X Yosemite) can even handle property names of 230 characters.

For all those browsers except IE, the maximum property length is the same as the maximum string length. IE9+ can handle a maximum string length of ~230 characters, but the limit for object keys is at 227 characters, just as in the other browsers.

The test didn't work in IE8 and Safari on iOS, presumably due to memory issues caused by the test code.

In a nutshell, it is safe to use long property names, even when taking it to extremes. As long as the strings themselves stay within the limits of what browsers can handle, you can use them as property names as well.

hashchange
  • 7,029
  • 1
  • 45
  • 41
  • 24
    Any *runtime* penalty for long keys on modern browsers? – Ahmed Fasih Jun 07 '15 at 07:48
  • 1
    @AhmedFasih I haven't tested it, so I don't know for sure. If there is a performance penalty, I'd assume it would have to do with comparing long strings. I'd be surprised if there are issues which matter in practice - unless the keys are _huge_ and numerous and you begin to hit memory constraints, e.g. on mobile. – hashchange Jul 27 '15 at 15:58
  • 8
    ES7 spec specify [a limit of 2^53 - 1 of "elements"](http://www.ecma-international.org/ecma-262/7.0/index.html#sec-ecmascript-language-types-string-type). But I think it's limited by the heap max size – mems Jan 06 '17 at 16:00
  • 6
    "*MDN is silent on the issue…*". [Not any more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/length). ;-) – RobG Dec 19 '17 at 04:50
  • 4
    So actual sizes are 2^27 = 0.125 GB , and 2^30 = 1 GB. That's plenty for me :) – Sorin C Jun 25 '18 at 15:53
38

No, there is no limit for the string length (as long as it fits into memory), and your implementation seems okay too. It's acutally quite common to have those 'turned around' arrays with e.g. boolean values. And as to the strings as keys: The strings are immutable symbols that are stored at a certain address, and what's actually used as the index for the array is that address (aka pointer aka reference) and not the string itself.

Ridcully
  • 23,362
  • 7
  • 71
  • 86
  • 4
    Interesting. Can you perhaps add a reference or source? – hashchange Mar 03 '15 at 12:55
  • 9
    In many languages, strings are immutable. Javascript is one of those languages. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Primitive_values – hartz89 Feb 18 '16 at 21:01
  • 4
    just to add some minor clarity for others. this means that you cannot perform an action that changes a string. you can manipulate and return a new string, but never actually change one – Patrick Apr 30 '17 at 19:39
  • 1
    The accepted answer is more practical, but this is the real answer. – theUtherSide Nov 04 '18 at 19:53
15

It appears as though with ECMAScript 2016, there is now a definitive answer to this question. According to the MDN Web Docs on string.length:

ECMAScript 2016 (ed. 7) established a maximum length of 2^53 - 1 elements. Previously, no maximum length was specified.

You can also find this specified in the ECMAScript® 2016 Language Specification:

The String type is the set of all ordered sequences of zero or more 16-bit unsigned integer values (“elements”) up to a maximum length of 253-1 elements.

Francis Bartkowiak
  • 1,374
  • 2
  • 11
  • 28