【发布时间】:2015-08-18 05:10:33
【问题描述】:
这个问题是多部分的-
(1a) JSON 是 JavaScript 的基础,那为什么没有 JSON 类型呢? JSON 类型将是格式化为 JSON 的字符串。在数据被更改之前,它将被标记为已解析/字符串化。一旦数据被更改,它就不会被标记为 JSON,并且需要重新解析/重新字符串化。
(1b) 在某些软件系统中,是否可能(意外地)尝试通过网络发送纯 JS 对象而不是序列化 JS 对象?为什么不尝试避免这种情况呢?
(1c) 为什么我们不能在不先对 JavaScript 对象进行字符串化的情况下直接调用 JSON.parse?
var json = { //JS object in properJSON format
"baz":{
"1":1,
"2":true,
"3":{}
}
};
var json0 = JSON.parse(json); //will throw a parse error...bad...it should not throw an error if json var is actually proper JSON.
所以我们别无选择,只能这样做:
var json0= JSON.parse(JSON.stringify(json));
但是,也有一些不一致的地方,例如:
JSON.parse(true); //works
JSON.parse(null); //works
JSON.parse({}); //throws error
(2) 如果我们一直在同一个对象上调用JSON.parse,最终它会抛出一个错误。例如:
var json = { //same object as above
"baz":{
"1":1,
"2":true,
"3":{}
}
};
var json1 = JSON.parse(JSON.stringify(json));
var json2 = JSON.parse(json1); //throws an error...why
(3) 为什么JSON.stringify 会在输入中无限添加越来越多的斜线?不仅很难读取调试结果,而且实际上会使您处于危险状态,因为一次 JSON.parse 调用不会给您返回一个普通的 JS 对象,您必须多次调用 JSON.parse 才能取回普通的 JS 对象。这很糟糕,意味着在给定的 JS 对象上多次调用 JSON.stringify 是非常危险的。
var json = {
"baz":{
"1":1,
"2":true,
"3":{}
}
};
var json2 = JSON.stringify(json);
console.log(json2);
var json3 = JSON.stringify(json2);
console.log(json3);
var json4 = JSON.stringify(json3);
console.log(json4);
var json5 = JSON.stringify(json4);
console.log(json5);
(4) 我们应该能够在不改变结果的情况下一遍又一遍地调用的函数的名称是什么(IMO JSON.parse 和 JSON.stringify 应该如何表现)?正如您在 cmets 中看到的那样,最好的术语似乎是“幂等”。
(5) 考虑到 JSON 是一种可用于网络对象的序列化格式,你不能调用 JSON.parse 或 JSON.stringify 两次甚至一次,这似乎是完全疯狂的情况下不会产生一些问题。为什么会这样?
如果您正在为 Java、JavaScript 或任何语言发明下一个序列化格式,请考虑这个问题。
IMO 给定对象应该有两种状态。序列化状态和反序列化状态。在具有更强类型系统的软件语言中,这通常不是问题。但是对于 JavaScript 中的 JSON,如果在同一个对象上调用 JSON.parse 两次,我们会遇到致命的异常。同样,如果我们在同一个对象上调用 JSON.stringify 两次,我们可能会进入不可恢复的状态。就像我说的应该有两种状态,只有两种状态,普通 JS 对象和序列化 JS 对象。
【问题讨论】:
-
parse从一个有效的 JSON 字符串返回一个有效的 JavaScript 对象,stringify从一个 JavaScript 对象返回一个有效的 JSON 字符串 -
你的第一个场景,你没有 JSON,你有一个 object。
-
1) 因为 JSON.parse 需要一个 JSON 字符串,而您正在为它提供一个 Javascript 对象,2) 同样的问题。 JSON.parse 将其转换为一个对象,并且您正在提供另一个 javascript 对象。
-
想想 javascript 中的
split和join。split将字符串转换为数组,而join将数组转换为字符串。你不能joinjoin的输出,因为它不是正确的类型。 -
(4) 你要找的词是幂等的。 en.wikipedia.org/wiki/Idempotence