JavaScript中的
所以我的问题是,在流行的JavaScript引擎(V8,JavaScriptCore,SpiderMonkey等)中,如何处理这个问题?显然,我们不希望我们的数组实际上被存储为具有键值的哈希映射!我们如何相对确定我们的数据被存储为一个真正的数组?
就我所见,引擎可以采取以下几种方法:
Array
和Object
之间的区别并不是很大。实际上,Array
主要添加了length
字段,因此您可以将Array
和Object
都用作数字数组:var ar = new Array();
ar[0] = "foo";
ar["bar"] = "foo";
var ob = new Object();
ob[0] = "foo";
ob["bar"] = "foo";
assert(ar[0] == ob[0] == ar["0"] == ob["0"] == ar.bar == ob.bar); // Should be true.
所以我的问题是,在流行的JavaScript引擎(V8,JavaScriptCore,SpiderMonkey等)中,如何处理这个问题?显然,我们不希望我们的数组实际上被存储为具有键值的哈希映射!我们如何相对确定我们的数据被存储为一个真正的数组?
就我所见,引擎可以采取以下几种方法:
Array
与Object
完全相同 - 作为具有字符串键的关联数组实现。Array
是一种特殊情况,具有类似于std::vector
的数组支持数字键,并且具有一些密度启发式算法,以防止在执行ar[100000000] = 0;
时出现疯狂的内存使用。Array
与Object
相同,并且所有对象都会获得一种启发式算法,以查看是否使用数组更有意义。- 我没有想到的非常复杂的东西。
如果有一个适当的数组类型(咳嗽WebGL类型数组咳嗽),那么这将更加简单。
length
属性的映射。如果是这样,那么移位或插入操作将打破索引(例如,从数组中移除一个值,它仍然从索引0开始,而不是1)。因此,至少还有一些其他的事情发生了。(当然,这并不一定说明实现存在问题) - Flambinor[0] == ob[0] == ar["0"] == ob["0"] == ar.bar == ob.bar
为真?'a' == 'a' == 'a'
是假的,因为它会被求值为true == 'a'
,然后再被求值为false
。 - Mike Samuelshift
被实现为通用方法,而不是仅适用于数组的特定方法。它可以很好地与普通对象一起使用。移除操作之所以有效是因为它获取第一个值,然后循环遍历所有值进行左侧赋值,最后删除最后一个元素并设置长度。 - Mike Samuelvar a = { 0: 0, 1: 1, length: 2 }; Array.prototype.shift.apply(a); alert(JSON.stringify(a))
。你应该可靠地得到{"0":1,"length":1}
。 - Mike Samuelslice
,这应该会想到我。有趣的发现。 - Flambino