JavaScript的JSON.stringify不能处理键索引(关联)数组吗?

5
在JavaScript中,您可以创建对象,例如:
var a = { foo: 12, bar: 34 };

或者是带有键名的数组,像这样:

var b = [];
b['foo'] = 56;
b['bar'] = 78;

它们有些相似,但显然不同。

现在奇怪的是,JSON.stringify似乎不能处理数组。没有错误或任何提示,JSON.stringify(b)的结果只是[]。

请参见此jsfiddle示例。我做错了什么吗?还是我对数组的工作方式有误解?


1
可能是重复的问题:JSON.stringify不适用于普通JavaScript数组 - Yuliam Chandra
3个回答

6

Javascript不支持关联数组(像PHP一样)。

var b = []; 明确声明一个数组,当您试图创建一个对象时。

Javascript中的数组只能包含索引数组的方法,而对象更多的是关联数组。

如果您将var b = [];更改为var b = {};,它将解决问题。

var b = {}明确声明一个对象。


你的意思是说,不支持关联数组?上面的代码可以正常工作(除了json stringify之外),之后我可以使用b['foo']和b['bar'],并且得到预期的结果。 - RocketNuts
我已经为您创建了一个Fiddle以便您理解。 http://jsfiddle.net/shaharlini/xLw2p54e/ JSON -> JavaScript对象表示法。请查看此处以从Mozilla MDN阅读更多信息: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify - Linial

5
Javascript数组是对象。有关详细信息,请参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Predefined_Core_Objects#Array_Object

注意:如果您在上面的代码中为数组运算符提供非整数值,则会在表示数组的对象中创建属性,而不是数组元素。

JSON仅支持Javascript的子集。有关详细信息,请参见http://www.json.org/

JSON基于两个结构:

  • 名称/值对的集合。在各种语言中,这被实现为对象、记录、结构、字典、哈希表、键控列表或关联数组。
  • 值的有序列表。在大多数语言中,这被实现为数组、向量、列表或序列。

具有在底层对象中创建属性的Javascript数组不适合这两个结构,因为它既有名称/值对的集合,又有值的有序列表,所以没有简单的方法直接表示这样的对象为JSON。

JSON.stringify方法在ECMAScript规范中定义。例如,请参见http://www.ecma-international.org/ecma-262/5.1/#sec-15.12.3

虽然有许多细节,但在这里相关的部分是如何将对象值转换为字符串:

如果Type(value)为Object,并且IsCallable(value)为false

  • 如果value的[[Class]]内部属性为“Array”,则返回使用参数value调用JA抽象操作的结果。
  • 否则,返回使用参数value调用JO抽象操作的结果。

给定您的数组,尽管向底层对象添加了参数,但结果是将数组元素的有序集合转换为字符串,而不是底层对象。

向数组对象添加参数没有问题,但它们不是数组的一部分,处理数组的函数或方法可能会忽略它们或任意处理它们。您已经看到JSON.stringify忽略了其他参数。其他函数可能会采取不同的方式处理它们-您将不得不在每种情况下找出。

虽然这样做并没有错,但如果您不向数组对象添加属性,则可能更容易理解。如果要添加属性,请从非数组对象开始。

而不是:

var b = [];
b['foo'] = 56;
b['bar'] = 78;

您可以使用以下方法:

var b = {};
b['foo'] = 56;
b['bar'] = 78;

1

enter image description here

这个截图是来自IE浏览器。可以看到数组仍然为空。
实际上,向数组中插入元素的方法有:
1. 使用push() 2. 在声明期间将元素插入数组
如果要将数组转换为字符串,则必须在数组中添加数据。
因此,现在您想要将键值对转换为字符串,因此您必须将对象作为JSON.stringify()的参数传递,如下所示:
var test = {};           // Object
test['a'] = 'test';
test['b'] = [];          // Array
test['b'].push('item');
test['b'].push('item2');
test['b'].push('item3');
var json = JSON.stringify(test);
alert(json);

您的问题的解决方案现在如下:

enter image description here

注意:Google Chrome的控制台会给出不同的结果,这是Google Chrome中的一个错误。

这不是IE的一个bug吗?(通常都是...)简单来说,这个代码是在打印Hello还是没有输出:var b=[]; b['x']='Hello'; alert(b['x']); - RocketNuts
但这不是向数组插入值的方式(请检查JavaScript的API文档)。此外,JavaScript中的所有内容都是对象,因此b ['x']表示法对于向数组中插入值是有效的,因为JavaScript认为与对象相对应创建了键值对。但是,一旦确定b是一个数组,它就不会将值插入数组中。因此,在这种情况下,数组将始终为空。因此,JSON.stringify()返回空数组。JSON.stringify()不可能出错。 - Vishal
无论使用哪种编程语言,始终要记住数组接受与索引相对应的值。这是编程语法。 - Vishal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接