Есть ли ограничение на длину ключа (строки) в объекте JS?

85

Итак, у нас был случай, когда у нас был бы объект, где ключ - это id (int), а значение - это строка. Но мы заметили, что в большинстве случаев мы ищем идентификатор на основе строки, поэтому мы решили отменить его и сделать строку ключом, а значение - идентификатором. Потому что таким образом, вместо того, чтобы просматривать каждый элемент и сравнивать значения, мы могли бы просто сделать var id = storage[text];. Ниже приведены примеры того, что мы сделали.

Вот пример старой реализации:

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

Вот пример новой реализации:

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

Я понимаю, что теперь строка является ключом, и можно получить тот же идентификатор для тех же строк. Но поскольку теперь строка может быть потенциально довольно большой (небольшая вероятность, но, вероятно, максимум 1 КБ на строку), существует ли ограничение длины, которое JS или Android webview накладывает на ключи объекта?

А также есть ли у этой реализации недостатки? Пока я не заметил никаких проблем, но как знать.

Шерзод
источник

Ответы:

98

Я немного исследовал это.

В MDN ничего не говорится об этом, как и в спецификации ( ES5 , ES6 ). Они только заявляют, что метод доступа к свойству должен быть строкой, без каких-либо оговорок - другими словами, в спецификации нет ограничений. В этом нет ничего удивительного.

Другое дело, как с этим справляются браузеры. Я настроил тест и запустил его в нескольких браузерах. Chrome 40 (Desktop), Chrome 40 (Android 5.1), Firefox 36, Opera 27 и IE9 + могут работать с именем свойства длиной до 227 символов. Safari 8 (OS X Yosemite) может обрабатывать даже имена свойств из 2 30 символов.

Для всех этих браузеров, кроме IE, максимальная длина свойства равна максимальной длине строки. IE9 + может обрабатывать максимальную длину строки ~ 2 30 символов, но ограничение для ключей объекта составляет 2 27 символов, как и в других браузерах.

Тест не работал в IE8 и Safari на iOS, предположительно из-за проблем с памятью, вызванных тестовым кодом.

Вкратце, длинные имена свойств безопасно использовать даже в крайних случаях. Пока сами строки остаются в пределах того, что могут обрабатывать браузеры, вы также можете использовать их как имена свойств.

хэш-обмен
источник
18
Какие-либо штрафы во время выполнения для длинных клавиш в современных браузерах?
Ахмед Фасих
@AhmedFasih Я не тестировал, поэтому точно не знаю. Если есть снижение производительности, я бы предположил, что это связано со сравнением длинных строк. Я был бы удивлен, если возникнут проблемы, которые имеют значение на практике - если только ключи не огромны и не многочисленны, и вы не начнете сталкиваться с ограничениями памяти, например, на мобильном телефоне.
hashchange
7
В спецификации ES7 указано ограничение в 2 ^ 53 - 1 «элементов» . Но я думаю, что это ограничено максимальным размером кучи
mems
6
« MDN умалчивает об этом… ». Больше нет . ;-)
RobG
3
Таким образом, фактические размеры составляют 2 ^ 27 = 0,125 ГБ, а 2 ^ 30 = 1 ГБ. Для меня этого достаточно :)
Sorin C
34

Нет, нет ограничений на длину строки (если она умещается в памяти), и ваша реализация тоже кажется хорошей. На самом деле довольно часто эти «перевернутые» массивы, например, имеют логические значения. А что касается строк как ключей: строки - это неизменяемые символы, которые хранятся по определенному адресу, и то, что фактически используется в качестве индекса для массива, - это этот адрес (он же указатель или ссылка), а не сама строка.

Чудакулли
источник
7
«Струны - неизменные символы»: Где вы этому научились?
Эндрю
4
Интересно. Можете ли вы добавить ссылку или источник?
hashchange 03
8
Во многих языках строки неизменяемы. Javascript - один из таких языков. developer.mozilla.org/en-US/docs/Web/JavaScript/…
hartz89
3
просто чтобы добавить немного ясности для других. это означает, что вы не можете выполнить действие, изменяющее строку. вы можете манипулировать и возвращать новую строку, но никогда не меняете ее
Патрик
Принятый ответ более практичен, но это настоящий ответ.
theUtherSide
6

Похоже, что в ECMAScript 2016 теперь есть окончательный ответ на этот вопрос. Согласно веб-документации MDN на string.length :

ECMAScript 2016 (изд. 7) установил максимальную длину 2 ^ 53-1 элементов. Ранее максимальная длина не указывалась.

Вы также можете найти это в спецификации языка ECMAScript® 2016 :

Тип String - это набор всех упорядоченных последовательностей из нуля или более 16-битовых целых чисел без знака («элементов») до максимальной длины 2 53 -1 элементов.

Фрэнсис Бартковяк
источник