JS 对象中的键(字符串)的长度有限制吗?

IT技术 javascript android android-webview javascript-objects
2021-02-16 13:54:33

所以我们有一个例子,我们会有一个对象,其中键是 id (int),值是字符串。但是我们注意到,大多数时候,我们是根据字符串查找 id 的,所以我们决定将其反转,将字符串作为键,值是 id。因为那样,我们无需遍历每个项目并比较值,而只需执行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
}

我知道现在字符串是关键,可以为相同的字符串获取相同的 id。但是由于现在字符串可能非常大(可能性很小,但每个字符串可能最多 1KB),JS 或 Android webview 是否对对象键设置了长度限制?

而且,这个实现有缺点吗?到目前为止我还没有注意到任何问题,但你永远不知道。

3个回答

我对此进行了一些研究。

MDN对这个问题保持沉默,规范(ES5ES6)也是如此。他们只声明属性访问器必须是一个字符串,没有任何限定——换句话说,就规范而言没有限制。这并不奇怪。

浏览器如何处理它是另一回事。我已经设置了一个测试并在许多浏览器中运行它。Chrome 40 (Desktop)、Chrome 40 (Android 5.1)、Firefox 36、Opera 27 和 IE9+ 最多可以处理 2 27 个字符的属性名称Safari 8 (OS X Yosemite) 甚至可以处理 2 30 个字符的属性名称

对于除 IE 之外的所有浏览器,最大属性长度与最大字符串长度相同。IE9+ 可以处理的最大字符串长度约为 2 30 个字符,但对象键的限制为 2 27 个字符,就像在其他浏览器中一样。

该测试在iOS上的IE8和Safari中均无效,推测是测试代码导致内存问题。

简而言之,使用长属性名称是安全的,即使是在极端情况下也是如此。只要字符串本身保持在浏览器可以处理的范围内,您也可以将它们用作属性名称。

@AhmedFasih 我还没有测试过,所以我不确定。如果有性能损失,我认为这与比较长字符串有关。如果在实践中存在重要的问题,我会感到惊讶 - 除非密钥很大而且数量众多,并且您开始遇到内存限制,例如在移动设备上。
2021-04-30 13:54:33
ES7 规范指定了 2^53 - 1 个“元素”的限制但我认为它受到堆最大大小的限制
2021-05-04 13:54:33
MDN 对这个问题保持沉默…… ”。没有了;-)
2021-05-06 13:54:33
所以实际大小是 2^27 = 0.125 GB 和 2^30 = 1 GB。这对我来说已经足够了:)
2021-05-12 13:54:33
任何运行12年的现代浏览器长的密钥?
2021-05-14 13:54:33

不,字符串长度没有限制(只要它适合内存),而且您的实现看起来也不错。使用布尔值等“翻转”数组实际上是很常见的。至于作为键的字符串:字符串是存储在某个地址的不可变符号,实际用作数组索引的是该地址(又名指针又名引用)而不是字符串本身。

在许多语言中,字符串是不可变的。Javascript 是其中一种语言。developer.mozilla.org/en-US/docs/Web/JavaScript/...
2021-04-25 13:54:33
只是为其他人增加一些轻微的清晰度。这意味着您不能执行更改字符串的操作。你可以操作并返回一个新的字符串,但永远不要真正改变一个
2021-05-01 13:54:33
有趣的。您能否添加参考或来源?
2021-05-10 13:54:33
接受的答案更实用,但这是真正的答案。
2021-05-10 13:54:33

似乎在 ECMAScript 2016 中,这个问题现在有了明确的答案。根据关于 string.lengthMDN Web 文档

ECMAScript 2016 (ed. 7) 建立了 2^53 - 1 个元素的最大长度。以前,没有指定最大长度。

您还可以在ECMAScript® 2016 语言规范中找到指定的内容

String 类型是由零个或多个 16 位无符号整数值(“元素”)组成的所有有序序列的集合,最大长度为 2 53 -1 个元素。