使用JavaScript[]文字的数组的长度是否真正反映了其在内存中的物理大小

Is the length of array using JavaScript [] literal really reflecting its physical size in memory?

本文关键字:内存 文字 JavaScript 数组 是否 使用      更新时间:2023-09-26

在JavaScript中,有两种方法可以定义数组:

var array = new Array(); // which is not preferred

var array = [];

【编辑以纠正误解】事实上,无论我使用[]还是new Array(),它们都是对象,因为我们可以定义

var object = [];
object["key"] = "value";
console.log(object.key); // gives "value"

我想知道如果我用[]定义一个"数组",如果我有以下代码,物理大小是多少:

var array = [];
array[1000] = "value";

如果它的行为像一个对象,那么它的物理大小应该只由键值对[1000]->"value"组成。但是,如果我使用console.log(array.length);输出数组的长度属性,它会给出1001,就好像在我刚刚插入的[1000]->"值"之前有1000个元素一样。

那么,使用[]定义的"数组"在内存中的物理大小应该是多少呢?

您的术语"物理尺寸"不清楚。你的意思是"数组中已定义元素的数量"吗?您使用了另一个不明确的术语,即"实际大小"。

阵列(无论创建如何)在"大小"方面具有以下特征:

  1. length。这是最后一个元素的索引,该元素包含一个值加一。

  2. 已定义元素的数量。这小于或等于长度。您可以通过执行类似array.reduce(function(n) { return n+1; }, 0)的操作来找到它,因为reduce跳过未定义的元素。filter也可以,所以你也可以做array.filter(function() { return true; }).length

  3. 内部大小。正如一位评论者所提到的,这是特定于引擎的,你没有办法或理由看到这一点。不同的引擎有不同的策略来管理数组的内部表示,此外,它们可能会在策略之间切换。因此,一个数组可能被表示为内存位置的连续块,但当它达到特定的稀疏度时,可能会将其表示更改为更适合稀疏数组的表示。如果它认为数组可能正在增长,它可能会预先分配内存块。因此,无法知道(或有理由关心)两个阵列"在内存中占用相同的物理大小"。

在另一个主题中,您似乎对数组和对象之间的区别感到困惑。CCD_ 7和CCD_。它们正是数组。然而,在JS中,数组继承了所有对象行为。换句话说,数组是一种特殊的对象,它提供了length的自动管理等功能,以及它们自己的原型方法。

.length属性是数组唯一真正特别的东西,它的值总是比最大的数字属性集多1。即arr.foo = 'bar'不影响.length的性质,但arr[100] = 'bar'影响。不过,两个赋值操作基本上都在做相同的事情,它们在对象上设置属性。

.length属性实际上只是允许您使用for (var i = 0; i < arr.length; i++)迭代数组,否则您将无法知道何时停止迭代。您应该使用.push.pop来操作数组,这样可以确保索引是连续的,或者以其他方式保持索引正常;如果这样做,则指向最高数字索引加1的.length正是唯一需要的行为。

然而,Javascript数组从根本上来说只是稀疏对象,只要您知道这种行为,您就可以随心所欲地使用它们。

来自文档-The length property represents an unsigned, 32-bit integer that is always numerically greater than the highest index in the array.

对于元素大小,没有直接的方法可以调用,但您可以使用filter-来确定大小

array.filter(function(value) { return value !== undefined }).length

var array = [];
array[1000] = "value";
alert(array.filter(function(value) { return value !== undefined }).length);

您从一些奇怪的假设开始。是的,数组是对象。。。就像JS中的所有东西一样。你可以把它看作是一个扩展对象的类,在对象之上有自己的功能。这并不意味着它不再是一个数组。

数组在索引方面并不是简单的键/值对。这就是它成为数组的原因。如果你把某个东西放在索引1000处,那么它需要使索引为0-1000才能使该数组具有该索引。所以,是的,如果你在arr[1000]上分配一个值,那么突然会有1001个总索引(1001个,因为它从0开始索引)。

无论用于创建Array对象的语法如何,这都是正确的。任一语法仍然创建相同类型的Array对象。。。这只是不同的语法。有些人避免使用new Array()的唯一原因是,如果你只给出一个正整数的参数,它会假设你想创建那么多空索引,而有些人会觉得这很困惑。再说一遍,这只是语法。。。


到Detractor:当您设置索引1000时,您可以pop()将其关闭,然后结束,仍然有999作为最高索引,即使它是未定义的。无论是否为所有这些索引设置了值,就数组而言,当您设置索引1000时,您会创建0-1000的索引,并且它会将这些索引视为数组中的实际索引,要求您使用Array方法将它们从数组中删除。0-999具有未定义的值这一事实并没有改变Array的情况。