You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript新手求助:JSON.stringify输出异常但对象含有效数据

为什么JSON.stringify输出空数组/Null,但直接访问属性能拿到值?

嘿,我刚入门JS的时候也踩过类似的坑,结合你的描述,大概率是这几个原因之一,一个个给你拆解明白:

1. 你给数组添加了自定义属性,JSON.stringify会直接忽略它们

这是最符合你场景的情况:你的myObject是一个数组,里面的每个元素也是数组,然后你给这些子数组加了ArmyName这类自定义字符串键属性。

举个完全匹配你问题的例子:

// 模拟你的数据结构
const myObject = [];
// 先往数组里push9个空数组
for(let i=0; i<9; i++){
  myObject.push([]);
}
// 给第一个子数组添加自定义属性
myObject[0].ArmyName = "ARMY_1";

console.log(myObject); // 控制台会显示子数组带有ArmyName属性
console.log(JSON.stringify(myObject)); // 输出 [[],[],[],[],[],[],[],[],[]]
myObject[0].ArmyName; // 能正常拿到"ARMY_1"

为啥会这样?因为JSON.stringify处理数组时,只会序列化数字索引对应的元素,完全忽略字符串键的自定义属性。数组本质是特殊对象,但JSON规范里数组是有序的值列表,非数字键的属性不在序列化范围内。

解决办法:别用数组存这类带自定义属性的数据,改成普通对象就行:

const myObject = [];
for(let i=0; i<9; i++){
  // 用普通对象代替数组
  myObject.push({});
}
myObject[0].ArmyName = "ARMY_1";

JSON.stringify(myObject); // 输出 [{"ArmyName":"ARMY_1"},{},{},{},{},{},{},{},{}]

2. 对象的属性是不可枚举的

如果你的数据存在普通对象里,但ArmyName是不可枚举属性,JSON.stringify也会跳过它。

比如用Object.defineProperty定义的属性,默认就是不可枚举的:

const myObject = [{}];
Object.defineProperty(myObject[0], 'ArmyName', {
  value: "ARMY_1",
  enumerable: false // 这个参数默认就是false
});

console.log(myObject); // 控制台能看到ArmyName(因为console会显示所有属性)
JSON.stringify(myObject); // 输出 [{}]
myObject[0].ArmyName; // 正常拿到值

解决办法:要么把属性改成可枚举的,要么手动收集属性来序列化:

// 方法1:定义时设置enumerable为true
Object.defineProperty(myObject[0], 'ArmyName', {
  value: "ARMY_1",
  enumerable: true
});

// 方法2:手动构建要序列化的对象
const serializableData = myObject.map(item => ({
  ArmyName: item.ArmyName
}));
JSON.stringify(serializableData);

3. 循环引用导致JSON.stringify返回Null

如果你的对象存在循环引用(比如obj.self = obj),JSON.stringify无法处理这种情况,会直接返回null。比如:

const army = { ArmyName: "ARMY_1" };
army.self = army;
const myObject = [army];

console.log(myObject); // 控制台能显示数据(会标注循环引用)
JSON.stringify(myObject); // 输出 null
myObject[0].ArmyName; // 正常拿到值

解决办法:初学阶段建议先避免在数据里出现循环引用;如果必须处理,可以手动排除循环引用的属性,或者用专门处理循环引用的工具库。

4. console.log的“延迟显示”坑(概率较低)

有时候控制台显示的对象是实时状态,而你调用JSON.stringify的时候,数据还没被填充。比如异步加载的数据,你在请求完成前就执行了JSON.stringify,但之后console.log的时候数据已经加载完成,所以看起来console有数据但stringify是空的。

不过你说直接访问myObject[0].ArmyName能拿到值,说明数据已经存在了,这个情况概率比较低,但也可以排查:在调用JSON.stringify之前,先打印myObject[0].ArmyName确认值已经存在。


内容的提问来源于stack exchange,提问作者Rackover

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:34:57