Чи існує обмеження довжини ключа (рядка) в об'єкті JS?


84

Отже, у нас був випадок, коли у нас був би об’єкт, де ключ - це 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 ставлять на клавіші об’єкта?

А також, чи має це впровадження недоліки? Наразі я не помічав жодних проблем, але ви ніколи не знаєте.

Відповіді:


96

Я трохи досліджував це.

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

Інша справа, як з цим справляються браузери. Я налаштував тест і запустив його в ряді браузерів. Chrome 40 (робочий стіл), Chrome 40 (Android 5.1), Firefox 36, Opera 27 та IE9 + можуть мати справу з назвою властивості довжиною до 27 символів. Safari 8 (OS X Yosemite) може навіть обробляти імена властивостей із 22 символів.

Для всіх цих браузерів, крім IE, максимальна довжина властивості така ж, як і максимальна довжина рядка. IE9 + може обробляти максимальну довжину рядка ~ 2 30 символів, але обмеження для об'єктних ключів становить 2 27 символів, як і в інших браузерах.

Тест не працював в IE8 та Safari на iOS, імовірно через проблеми з пам'яттю, спричинені тестовим кодом.

У двох словах, безпечно використовувати довгі назви властивостей, навіть коли доводити їх до крайнощів. Поки самі рядки залишаються в межах того, що можуть обробляти браузери, ви можете використовувати їх і як імена властивостей.


17
Будь-яке час виконання пенальті для довгих ключів на сучасних браузерах?
Ахмед Фасіх

@AhmedFasih Я його не тестував, тому точно не знаю. Якщо є покарання за продуктивність, я вважаю, що це буде пов’язано з порівнянням довгих рядків. Буду здивований, якщо на практиці будуть важливі проблеми - якщо клавіші не є величезними та численними, і ви не почнете обмежувати пам’ять, наприклад, на мобільному.
hashchange

7
Специфікація ES7 визначає обмеження 2 ^ 53 - 1 для "елементів" . Але я думаю, що це обмежено максимальним розміром купи
меми

6
" MDN мовчить щодо цього питання ... ". Більше ні . ;-)
RobG

2
Тож фактичні розміри становлять 2 ^ 27 = 0,125 ГБ і 2 ^ 30 = 1 ГБ. Для мене цього достатньо :)
Sorin C

34

Ні, обмеження довжини рядка не існує (якщо воно поміщається в пам’ять), і ваша реалізація теж здається нормальною. Гостро часто зустрічаються такі, що "обертаються" масиви, наприклад, з логічними значеннями. Що стосується рядків як ключів: рядки - це незмінні символи, які зберігаються за певною адресою, і що насправді використовується як індекс для масиву - це ця адреса (вона ж вказівник, яка також є посиланням), а не сам рядок.


7
"Рядки - це незмінні символи": Де ви це дізналися?
Ендрю

4
Цікаво. Чи можете ви, можливо, додати посилання чи джерело?
hashchange 03.03.15

8
У багатьох мовах рядки незмінні. Javascript - одна з таких мов. developer.mozilla.org/en-US/docs/Web/JavaScript/…
hartz89

3
просто щоб додати трохи незначної ясності для інших. це означає, що ви не можете виконати дію, яка змінює рядок. Ви можете маніпулювати і повертати новий рядок, але ніколи насправді не змінюйте його
Патрік

Прийнята відповідь є більш практичною, але це справжня відповідь.
theUtherSide

5

Схоже, що в ECMAScript 2016 тепер є остаточна відповідь на це питання. Згідно з веб-документами MDN на string.length :

ECMAScript 2016 (видання 7) встановив максимальну довжину 2 ^ 53 - 1 елементів. Раніше не було вказано максимальної довжини.

Ви також можете знайти це, зазначене в специфікації мови ECMAScript® 2016 :

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.