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]时,是否会重新定位此项下的项
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