为什么数组甚至使用字符串键保留这么多空格?

时间:2013-03-04 22:07:10

标签: javascript arrays hashmap

我有以下数组:

var arr = [];
console.log(arr.length); //Output: 0

arr["1231321"] = "abcd";
console.log(arr.length); //Output: 1231322

arr["1231321".toString()] = "abcd";
console.log(arr.length); //Output: 1231322

arr["a1231321"] = "abcd";
console.log(arr.length); //Output: 0

arr["1231321a"] = "abcd";
console.log(arr.length); //Output: 0

这是小提琴:http://jsfiddle.net/HcrcR/

当我将我的arr更改为var arr = {};时,它就可以了。

但是它的原因是什么,即使我使用字符串键它开始从键推送数据?

3 个答案:

答案 0 :(得分:6)

  

我有以下数组/ hashmap:

这是JavaScript术语中的Array

var arr = [];
console.log(arr.length); //Output: 0

这是预期的,它是一个空阵列。

arr["1231321"] = "abcd";
console.log(arr.length); //Output: 1231322

length属性的大小总是+1而不是最高索引。使用字符串并不重要,ArrayObject的键始终是JavaScript中的字符串。

  

此Array对象的length属性是一个data属性,其值始终在数值上大于名称为数组索引的每个deletable属性的名称。

Source

arr["1231321".toString()] = "abcd";
console.log(arr.length); //Output: 1231322

在字符串上调用toString()不会做任何事情(它已经是一个字符串)。

arr["a1231321"] = "abcd";
console.log(arr.length); //Output: 0

同样期望,您在Array上设置了一个看起来不像索引的属性。

arr["1231321a"] = "abcd";
console.log(arr.length); //Output: 0

见上文。在字符串内部没有解析来尝试获取数字。

  

当我将我的arr更改为var arr = {};时,它就可以了。

这就是对象在JavaScript中的工作方式。它们只是一堆字符串键值。

答案 1 :(得分:4)

JavaScript中的

Array != Object (or hashmap)。因此,添加到不是整数索引的数组的属性不会影响Array.length

请注意,没有保留空间,只是因为长度为1231321,并不意味着所有空间都被分配,JavaScript数组不必使用连续内存,如果它们是疏。实际上,它们仅作为优化连续,默认行为是它们就像对象一样是哈希映射。

如果您需要知道对象拥有的所有密钥,则需要使用https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/keys

但是,你不应该混合这两个概念,在JS中,你应该使用数组(数字索引)或对象(任何索引)

当你这样做时

arr["1231321"] = "abcd";

相同
arr[1231321] = "abcd";

这会影响数组的length。然而,

arr["1231321a"] = "abcd"

不创建新的数组索引(只是一个新的对象属性),它不会影响length属性

请注意,如果您依次键入以下命令,则问题中的示例不正确

arr = [];
arr["1231321"] = "abcd";
console.log(arr.length); //Output: 1231322
arr["a1231321"] = "abcd";
// Output: 1231322, should be the same as before, not undefined
console.log(arr.length); //Output: 1231322

http://jsfiddle.net/tWCa4/

答案 2 :(得分:2)

它可以使用前2个字符串作为索引,因为它们可以被解析为数字。

当你传递一些无法解析为整数的东西时,数组会将其作为数组的属性而不是条目附加。

当您将其定义为对象时,它将充当对象并将所有内容视为字符串属性。长度将始终定义为javascript中数组的最高值+ 1。

所以要清楚

var x = [] 

创建一个新的Array,它将尝试将其输入解析为整数并将它们添加到数组中,否则将它们指定为属性。

var x = {}

将创建一个Object,它作为一组无序属性使用,除非您自定义x.length = y,否则它将没有长度,在这种情况下它只是另一个没有特殊含义的属性。