cal*_*lum 19 javascript arrays object
我正在使用JavaScript编写Google Chrome扩展程序,我想使用数组来存储一堆对象,但我希望索引是特定的非连续 ID号.
(这是因为我需要能够使用来自我控制之外的其他来源的ID号来有效地查找值.)
例如:
var myObjects = [] ;
myObjects[471] = {foo: "bar"} ;
myObjects[3119] = {hello: "goodbye"}
Run Code Online (Sandbox Code Playgroud)
当我这样做时console.log(myObjects),在控制台中我看到整个阵列打印出来,显示了数千个"缺失"的索引undefined.
我的问题是:这有关系吗?这会浪费任何记忆吗?
即使它没有浪费内存,当我循环遍历数组时,如果我必须手动跳过每个缺失值,它会浪费CPU吗?
我尝试使用对象而不是数组,但似乎你不能使用数字作为对象键.我希望有更好的方法来实现这一目标吗?
gbl*_*zex 13
首先,每个人,请了解for-in statement所谓的枚举(尽管它是一个IterationStatement),以区别于迭代.这非常重要,因为它会导致特别是初学者之间的混淆.
要回答OP的问题:它不占用更多的空间(测试)(你可以说它依赖于实现,但我们谈论的是谷歌Chrome扩展!),它也不慢(测试).
但我的建议是:使用合适的东西! 在这种情况下:使用对象!
您想要用它们做什么显然是一种散列机制,无论如何都将键转换为字符串,这样您就可以安全地使用对象来完成此任务.
我不会向你展示很多代码,其他答案已经完成了,我只想说清楚.
// keys are converted to strings
// (numbers can be used safely)
var obj = {}
obj[1] = "value"
alert(obj[1]) // "value"
alert(obj["1"]) // "value"
Run Code Online (Sandbox Code Playgroud)
关于稀疏数组的注意事项
稀疏数组不会浪费任何空间的主要原因是因为规范没有这么说.没有点哪里会需要属性访问,以检查是否内部[[类]]属性是一个"阵列",然后创建从每个元素0 <I <len个是值undefined等,它们恰好是undefined当该toString方法迭代数组.它基本上意味着他们不存在.
11.2.1属性访问者
生成MemberExpression:MemberExpression [ Expression ]的计算方法如下:
GetValue(baseReference). GetValue(propertyNameReference). CheckObjectCoercible(baseValue). ToString(propertyNameValue). Reference的值,其基值为baseValue,其引用名称为propertyNameString,其严格模式标志为strict. 除了在步骤1中计算包含的CallExpression之外,生产CallExpression:CallExpression [ Expression ]的计算方式完全相同.
ECMA-262第5版(http://www.ecma-international.org/publications/standards/Ecma-262.htm )
您可以在这里简单地使用一个对象,将键作为整数,如下所示:
var myObjects = {};
myObjects[471] = {foo: "bar"};
myObjects[3119] = {hello: "goodbye"};
Run Code Online (Sandbox Code Playgroud)
这使您可以将任何东西存储在对象,函数等上。要枚举(因为现在是一个对象),则需要一个不同的语法,例如一个for...in循环:
for(var key in myObjects) {
if(myObjects.hasOwnProperty(key)) {
console.log("key: " + key, myObjects[key]);
}
}
Run Code Online (Sandbox Code Playgroud)
对于您的其他特定问题:
我的问题是:这有关系吗?这会浪费内存吗?
是的,它浪费了一部分内存用于分配(更多的用于迭代),但这并不重要,这取决于键的间隔。
而且即使没有浪费内存,也可以肯定,每当我遍历数组时,如果我必须手动跳过每个丢失的值,就会浪费CPU?
是的,这里使用了额外的循环。
我尝试使用对象而不是数组,但是似乎不能将数字用作对象键。我希望有一个更好的方法来实现这一目标?
当然可以!,请参阅上文。