所以,我在考虑如何在JavaScript中将数组存储在内存中。
我已经阅读了How are JavaScript arrays represented in physical memory?,但我找不到答案。
我在想的更多是关于阵列单元的内存位置。例如,在C中,您需要在定义数组时定义数组的大小。有了这个,C定义了整个内存块,它可以查看每个单元的确切位置。
例如:
int array[10]; // C knows the memory location of the 1st item of the array
array[3] = 1 // C can do that, because it can calculate the location
// of array[3] by doing &array + 3 * (int size)
在JS中,你可以在将内存分配给其他东西之后增加数组的大小,这意味着JS不能使用“块”类型的数组。
但是如果数组不是单个内存块,JS如何计算每个单元的位置? JS数组是否遵循链表类型的结构?
答案 0 :(得分:3)
与C或其他专有的编译语言不同,JavaScript是ECMAScript实现。实现的细节不是标准化的,并且特定于每个供应商的实现。简而言之,语言实现方式的低级细节是一个黑盒子,虽然您可以深入了解特定供应商实现的内部,但是没有标准,实现将因供应商而异。另一个。
答案 1 :(得分:2)
我建议大家的一件事是node.js最近成为Chrome V8的一等公民,所以我建议学习V8,不仅要看它如何处理这些实现细节,还要看其中的原因。
首先,本文应该证明对读者有益,因为它专注于编写优化的同构JavaScript:
上面的文章详细介绍了JIT(即时)编译器的工作原理,因此您应该能够在阅读之后得出确切的问题。
这是一个exerpt:
数组:避免使用稀疏数组,其中键不是增量数字。其中没有每个元素的稀疏数组是哈希表。这种阵列中的元素访问起来更加昂贵。另外,尽量避免预先分配大型数组。随着你的成长,你的成长会更好。最后,不要删除数组中的元素。它使密钥稀疏。
其次,我还建议阅读本文,然后针对V8向外工作: http://www.jayconrod.com/posts/52/a-tour-of-v8-object-representation
第三,作为一个关键的奖金事实,我不久前读到了这个答案,我不时在精神上重新审视它。我很惊讶我现在才发现它。我直接用Google搜索"堆栈溢出优化火车轨道"并找到了它。感谢Google:Why is it faster to process a sorted array than an unsorted array?
是的,这个答案确实有27,000张正票。
那篇文章讨论了分支预测,我希望你能够意识到这一点,因为它可能会影响你如何处理数据,而不仅仅是数组。再次,请注意我链接的第一篇文章,并在描述order of keys on an Object
时注意。
通过了解实施细节并理解为什么问题以这种方式解决,可以优化性能。
最后,一切都是JavaScript中的对象,除非它是标量值,我们称之为基元 - 字符串,数字,布尔值等。
这是一个引人深思的例子:
const arr = ['one', 'two', 'three']
const sameArr = {
0: 'one',
1: 'two',
2: 'three',
}
然后我们可以将我们的数组解构为对象:
const yolo = ['one', 'two', 'three']
const {
0: one,
1: two,
2: three,
} = yolo
console.log('Pretty cool:', one, two, three)

您可以从该示例中获得一些提示,了解为什么更改键的顺序可能会对底层哈希表造成严重破坏。仅仅因为你无法看到钥匙并不意味着它们不会受到影响。
在上面的例子中,如果是地图,你可以sameArr.get('0')
,JavaScript可以合理地知道数字表中的确切位置。
由于ES6的大修,我还建议您仔细阅读旧的JavaScript资料。我觉得最方便的是指导您使用V8材料。