这是关于语言内部运作的一般问题。我想知道javascript如何获得索引的价值。例如,当你写array[index]
时,它是否循环遍历数组,直到找到它为止?或通过其他方式?我问的原因是因为我编写了一些代码,我循环遍历数组以匹配值并在网格上找到点,我想知道是否会通过创建像array[gridX][gridY]
这样的数组来增加性能,或者它是否会使差异。我现在正在做的是通过一个平面数组的对象,网格点作为这样的属性:
var array = [{x:1,y:3}];
然后循环并使用对象属性中的那些坐标来识别和使用对象中包含的值。
我的想法是,通过实现多维网格,它可以更直接地访问它们,因为可以通过说array[1][3]
而不是循环执行来指定网格点:
for ( var a = 0; a < array.length; a += 1 ){
if( array[a].x === 1 && array[a].y === 3 ){
return array[a];
}
}
或类似的东西。
任何见解都会受到赞赏,谢谢!
答案 0 :(得分:2)
例如,当你编写数组[index]时,它是否循环遍历数组,直到找到它为止?或通过其他方式?
这是实现定义的。 Javascript可以同时包含数字和字符串键,并且第一个Javascript实现确实可以通过这种方式进行缓慢的循环访问。
然而,现在大多数浏览器效率更高,并且存储数组分为两部分,一个是数字索引的打包数组,另一部分是哈希表。这意味着访问数字索引(对于没有空洞的密集数组)是O(1),访问字符串键和稀疏数组是通过哈希表完成的。
我想知道是否会通过创建和数组[gridX] [gridY]来增加性能,或者它是否会产生影响。我现在正在做的是使用网格点作为属性的平面数组,如
array[{x:1,y:3}]
使用2维数组。它是一个更简单的解决方案,最有可能为您提供足够的效率。
执行此操作的另一个原因是,当您将对象用作数组索引时,实际发生的事情是将对象转换为字符串,然后将该字符串用作哈希表键。所以array[{x:1,y:3}]
实际上是array["[object Object]"]
。如果你真的想要,你可以覆盖toString方法,所以不是所有的网格点序列化到相同的值,但我不认为它值得麻烦。
答案 1 :(得分:0)
无论是数组还是对象,任何现代javascript引擎中的底层结构都是哈希表。需要证明吗?分配一个包含1000000000个元素的数组,并注意速度和内存增长不足。 Javascript数组是Object的一个特例,它提供length
方法并将键限制为整数,但它很稀疏。
所以,你真的在一起链接哈希表。当您在a[x][y]
中嵌套表时,您创建了多个哈希表,并且需要多次访问才能解析对象。
但哪个更快?这是一个jsperf,分别测试分配和访问的速度:
http://jsperf.com/hash-tables-2d-versus-1d
http://jsperf.com/hash-tables-2d-versus-1d/2
在我的机器上,嵌套方法更快。
直觉与剖析器无法匹配。
更新:有人指出,在某些有限的实例中,数组实际上是下面的数组。但由于数组是专门的对象,你会发现在这些相同的实例中,对象也被实现为数组(即,{0:'hello', 1:'world'}
在内部实现为数组。但这不应该吓到你使用具有数万亿个元素的数组,因为一旦它不再有意义,这个特殊情况就会被丢弃。
答案 2 :(得分:0)
要回答您的初始问题,在JavaScript中,数组只不过是一种特殊类型的对象。如果你设置一个像这样的新数组:
var someArray = new Array(1, 2, 3);
你最终得到的Array
对象的结构看起来或多或少,就像这样(注意:这严格来说就是它所存储的数据。 。Array
对象有一个 LOT 更多:
someArray = {
0: 1,
1: 2,
2: 3
}
Array
对象添加到等式中的内容是在操作中构建的,允许您在习惯的[1, 2, 3]
概念中与其进行交互。例如,push()
将使用数组的length
属性来确定应添加下一个值的位置,在该位置创建值,并递增length
属性。
然而(回到最初的问题),在访问它存储的值时,数组结构中没有任何东西与任何其他属性有任何不同。没有固有的循环或类似的东西。 。 。访问someArray[0]
与访问someArray.length
基本相同。
实际上,您必须使用someArray[N]
格式访问标准数组值的唯一原因是,存储的数组值是数字索引的,并且您无法直接访问以数字开头的对象属性“点”技术(即someArray.0
无效,someArray[0]
不是)。
现在,诚然,这是JavaScript中Array
对象的一个非常简单的视图,但是,就您的问题而言,它应该足够了。如果您想了解更多关于内部运作的信息,可以在此处找到大量信息:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
答案 3 :(得分:0)
具有直接访问权限的单维哈希表:
var array = {
x1y3: 999,
x10y100: 0
};
function getValue(x, y) {
return array['x' + x + 'y' + y];
}