Javascript数组对象与数组类似对象 - 澄清

时间:2012-02-07 21:41:37

标签: javascript arrays json object associative-array

我试图将声明为数组对象的类似数组的对象进行字符串化,并发现JSON.stringify在定义为数组对象时未正确处理类似数组的对象。

有关更清晰的信息,请参阅下文 - > jsFiddle

var simpleArray = []; //note that it is defined as Array Object 

alert(typeof simpleArray); // returns object -> Array Object

simpleArray ['test1'] = 'test 1';
simpleArray ['test2'] = 'test 2';

alert(JSON.stringify(simpleArray)); //returns [] 

当我改变

时,它工作正常并且还给我{"test1":"test 1","test2":"test 2"}

var simpleArray = [];var simpleArray = {};

有人可以提供一些亮点或一些参考资料,我可以阅读更多内容吗?

修改:

问题:当typeof simpleArray = []simpleArray = {}返回对象时,为什么JSON.stringify在这两种情况下都无法返回{"test1":"test 1","test2":"test 2"}

7 个答案:

答案 0 :(得分:4)

区别在于指数。使用数组[]时,索引只能是正整数。

以下是错误的:

var array = [ ];
array['test1'] = 'test 1';
array['test2'] = 'test 2';

因为test1test2不是整数。为了解决这个问题,您需要使用基于整数的索引:

var array = [ ];
array[0] = 'test 1';
array[1] = 'test 2';

或者如果你声明一个javascript对象,那么属性可以是任何字符串:

var array = { };
array['test1'] = 'test 1';
array['test2'] = 'test 2';

相当于:

var array = { };
array.test1 = 'test 1';
array.test2 = 'test 2';

答案 1 :(得分:2)

您不需要数组。如果你想在JavaScript中使用“关联数组”,你真的想要一个对象{}

您可以使用instanceof Array区分它们:

[] instanceof Array // true
({}) instanceof Array // false

编辑:它可以处理它。它序列化了数组的所有元素。但是,要成为元素,必须有数字键。在这种情况下,没有。

这对JSON来说并不是唯一的。它与toSourcelength属性一致。

答案 2 :(得分:2)

  

“有人可以透露一些亮点或某些参考资料吗?

当您处理JSON数据时,可以参考json.org阅读有关规范要求的内容。

JSON中,Array是由,分隔的值的订单列表。

enter image description here

因此JSON.stringify()只是忽略了任何无法表示为简单有序列表的内容。

所以,如果你这样做......

var simpleArray = [];
simpleArray.foo = 'bar';

...你还在给一个数组,所以它只期待数字索引,而忽略其他任何东西。

由于JSON与语言无关,因此使用JSON的方法需要决定哪种语言结构最适合每个JSON结构。

所以JSON有以下结构......

{} // object
[] // array

您应该注意,尽管看起来与JavaScript对象和数组非常相似,但它们并不完全相同。

用于创建JavaScript结构的任何JSON结构必须符合JSON结构允许的结构。这就是为什么非数字属性被删除排除。

虽然JavaScript不介意,JSON不会容忍他们。

答案 3 :(得分:1)

JSON.stringify遇到数组时,它会以与for0的{​​{1}}循环类似的方式进行迭代,以查找值。例如:

simpleArray.length

因此,对它设置属性对JSON完全不可见。

但是,使用var a = []; a[5] = "abc"; alert(JSON.stringify(a)); // alerts [null,null,null,null,null,"abc"] 定义对象会使JSON将其视为对象,因此它会遍历对象的属性(不包括原型链中的继承属性)。通过这种方式,它可以找到您的{}test1属性,并成功返回您期望的内容。

答案 4 :(得分:1)

Array实例与其他对象之间的差异在ECMAScript Language Specification, Edition 5.1第15.4节中指定。

你会发现虽然你可以使用括号属性访问器语法与所有对象引用 -

objRef[propertyName]

- Array个实例很特别。只使用一个参数值,该字符串表示是一个小于2 32 -1的无符号32位整数值的参数值,它访问封装数组结构的一个元素,而写访问会影响{{{ 1}} instance的Array属性。

第15.12节相应地指定length对象及其JSON方法。

答案 5 :(得分:0)

在Javascript中,一切都是对象,所以即使是数组。 这就是你得到的原因:

>> var l = [1, 2];
>> typeof l
"object"

数组的存储方式与对象相同。因此,实际上,数组只是哈希表对象。访问时提供的索引,例如

>> l[0]

不会被解释为偏移量,而是经过哈希处理然后进行搜索。

So Arrays,只是对象(带有一些内置的数组方法),因此您可以将它们视为对象并将值放在某个键下。 但只有那些用数字索引的键才能用来计算长度。

>> var l = []
>> l.length
0
>> l[5] = 1;
>> l.length
6
>> l
[undefined, undefined, undefined, undefined, undefined, 1]
>> l.hello = "Hello"
>> l.length
6

阅读Array - MDN了解详情 和Associative Arrays considered harmful为什么你不应该这样做。

答案 6 :(得分:-1)

您的代码在语义上并不正确,但是因为大多数JavaScript引擎在程序员身上都非常好,所以它们允许这些类型的错误

快速测试案例:

var a = [];
a.b = "c";
console.log(JSON.stringify(a));//yields [], and not {"b":"c"} as you might expect

这可能是因为JSON.stringify中的某些严格性仍将a视为Array。 我不会过分担心它。这种情况不应该出现在您的程序中,因为它是一个错误。 JSLint是一种流行的工具,用于捕获代码中的这些以及更多潜在问题。