Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/458.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript数组随机索引插入和删除_Javascript_Arrays - Fatal编程技术网

JavaScript数组随机索引插入和删除

JavaScript数组随机索引插入和删除,javascript,arrays,Javascript,Arrays,我使用随机创建的索引将一些项插入数组中,例如: var myArray = new Array(); myArray[123] = "foo"; myArray[456] = "bar"; myArray[789] = "baz"; ... 换句话说,数组索引不是以零开始的,它们之间会有“数字间隙”。我的问题是: 即使没有赋值,这些数字间隙是否会以某种方式分配(并因此占用一些内存) 当我从上面的示例中删除myArray[456]时,是否会重新定位此项下的项 编辑: 关于我关于插入/删除后项

我使用随机创建的索引将一些项插入数组中,例如:

var myArray = new Array();
myArray[123] = "foo";
myArray[456] = "bar";
myArray[789] = "baz";
...
换句话说,数组索引不是以零开始的,它们之间会有“数字间隙”。我的问题是:

  • 即使没有赋值,这些数字间隙是否会以某种方式分配(并因此占用一些内存)
  • 当我从上面的示例中删除myArray[456]时,是否会重新定位此项下的项
编辑: 关于我关于插入/删除后项目重新定位的问题/担忧,我想知道内存而不是索引会发生什么。更多信息来自:

链表有几个优点 在动态数组上。插入 元素位于列表的特定点 是一个常数时间操作,而 随机插入动态数组 位置将需要移动一半的 元素的平均值,以及所有 最坏情况下的元素。而一 可以从数组中“删除”元素 在恒定的时间内通过某种方式标记 其插槽为“空”,这导致 阻碍经济增长的碎片化 迭代的性能

这些数字差距会以某种方式缩小吗 分配(因此采取一些措施) 记忆)即使他们没有 赋值

不,请看

当我从upper中删除myArray[456]时 例如,此项目下面的项目 搬迁

否,如果在460处有项目,则在删除456后,该项目将保留在那里。如果您希望以下各项适当下移,请使用如下方法:

myArray.splice(456, 1)
“差距”不会导致分配,而且不会“转移”其索引中的现有值

即使没有赋值,这些数字间隙是否会以某种方式分配(并因此占用一些内存)

不,JavaScript数组根本不是真正的数组(见下文),未使用的索引不消耗内存

当我从上面的示例中删除myArray[456]时,是否会重新定位此项下的项

如果您谈论的是数组索引,这取决于您删除它的方式:如果您使用
delete
关键字,则为否。如果您使用
splice
功能或类似功能,则为是。就内存而言,不,其他条目不会重新定位(不管是什么),并且由不再存在的条目引用的任何内存(无论是由于
删除
还是
拼接
弹出
或类似原因)都可以由垃圾收集器回收。在JavaScript中,链表与数组或普通的旧对象相比几乎没有优势,而且您很少看到它们。添加到JavaScript数组(或对象)很可能是一个近乎恒定的时间操作(实现可能需要进行哈希运算,可能需要遍历B树结构或类似结构,但这完全是特定于实现的),删除也是如此

正如Zevon所指出的,对于您所描述的,您可能根本不需要数组。如果需要
length
属性或依赖它的某个数组函数,则实际上只需要一个数组。否则,最好使用普通的旧对象:

var obj = {};
obj[123] = "foo";
obj[456] = "bar";
obj[789] = "baz";
这是非常有效的JavaScript。括号中使用的值(123等)强制为字符串(无论是处理数组还是普通对象),因此键实际上是“123”等(无论是使用
数组
还是
对象
)。您甚至可以使用
控制结构()中的
for..遍历它们


我所说的“…根本不是数组”是什么意思?从字面上说。JavaScript对象是键->值映射,JavaScript数组只不过是具有键和值、对数字字符串键的特殊处理以及特殊的
length
属性的对象。虽然我们通常将数组“索引”写为数字,但与所有属性名称一样,它们都是字符串-
a[0]
被转换为
a[“0”]
(尽管只要行为符合规范,实现可以自由优化)。本节第15.4节涵盖了这一点,该节从本段开始:

数组对象对某类属性名给予特殊处理。当且仅当ToString(ToUint32(P))等于P且ToUint32(P)不等于2^32时,属性名P(以字符串值的形式)才是数组索引−1.属性名为数组索引的属性也称为元素。每个数组对象都有一个
length
属性,其值总是小于2^32的非负整数。
length
属性的值在数字上大于名称为数组索引的每个属性的名称;每当 创建或更改数组对象的属性时,根据需要调整其他属性以保持此不变。具体地说,每当添加名称为数组索引的属性时,如果需要,
length
属性将更改为比该数组索引的数值多一个;无论何时更改
length
属性,名称为数组索引的每个属性的值都不小于新的 长度将自动删除。此约束仅适用于数组对象的自身属性,不受从其原型继承的长度或数组索引属性的影响


这是第一个问题,“这完全取决于浏览器的实现…”不,不是,除非实现与规范不一致。@t.J.Crowder:哇,谢谢你的更正。我查阅了规范的相关部分并更新了我的答案。与您的问题无关,但是,在做这种事情时,您可能会考虑使用一个对象而不是VaMyReals= {}谢谢您的长而翔实的回答。当我使用普通的旧对象而不是数组时,用它的值删除键的最佳方法是什么?@Tomi:
delete
canb