我试图将声明为数组对象的类似数组的对象进行字符串化,并发现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"}
?
答案 0 :(得分:4)
区别在于指数。使用数组[]
时,索引只能是正整数。
以下是错误的:
var array = [ ];
array['test1'] = 'test 1';
array['test2'] = 'test 2';
因为test1
和test2
不是整数。为了解决这个问题,您需要使用基于整数的索引:
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来说并不是唯一的。它与toSource
和length
属性一致。
答案 2 :(得分:2)
“有人可以透露一些亮点或某些参考资料吗?
当您处理JSON
数据时,可以参考json.org阅读有关规范要求的内容。
在JSON
中,Array
是由,
分隔的值的订单列表。
因此JSON.stringify()
只是忽略了任何无法表示为简单有序列表的内容。
所以,如果你这样做......
var simpleArray = [];
simpleArray.foo = 'bar';
...你还在给一个数组,所以它只期待数字索引,而忽略其他任何东西。
由于JSON
与语言无关,因此使用JSON
的方法需要决定哪种语言结构最适合每个JSON
结构。
所以JSON有以下结构......
{} // object
[] // array
您应该注意,尽管看起来与JavaScript
对象和数组非常相似,但它们并不完全相同。
用于创建JavaScript
结构的任何JSON
结构必须符合JSON
结构允许的结构。这就是为什么非数字属性被删除排除。
虽然JavaScript
不介意,JSON
不会容忍他们。
答案 3 :(得分:1)
当JSON.stringify
遇到数组时,它会以与for
到0
的{{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是一种流行的工具,用于捕获代码中的这些以及更多潜在问题。