为了更准确,我理解为什么技术上发生 - 因为undefined
不是有效的JSON类型:
var breakfast = {
"cereal" : "fruit loops",
"pastry" : undefined
};
console.log(breakfast);
// -> { cereal: 'fruit loops', pastry: undefined }
console.log(JSON.stringify(breakfast));
// -> {"cereal":"fruit loops"}
我的问题是 - 为什么这被认为是可接受的行为?我有理由将undefined
作为API或其他任何内容的一部分传递。这似乎有些危险 - 为什么函数不会引发错误而不是肆无忌惮地在没有警告的情况下更改我的数据?这似乎是JS的一个运行线程。
答案 0 :(得分:6)
答案在于ECMA-262 spec。在24.3.2 JSON.stringify ( value [ , replacer [ , space ] ] )
部分中,规范明确指出:
注2
未呈现未定义值。
此外:
注5
没有JSON表示的值(例如未定义和函数)不会生成String。相反,他们生产 未定义值。在数组中,这些值表示为 字符串 null 。在对象中,不可代表的值会导致该属性 被排除在字符串化之外。
因此,JSON.stringify()
正如您使用它完全符合现有的ECMA规范。
即使使用替换程序,而没有专门指定您自己的函数,默认的替换程序规则也指出只应追加 items :
24.3.2第4.b.5.g小节
如果项不是未定义且项目前不是 对propertyList
答案 1 :(得分:3)
JSON意味着与语言无关。它已经支持null
。支持undefined
也会强制处理JavaScript在其他语言上的特性之一,这会破坏易于互操作的目的。
'JSON's design goals were for it to be minimal, portable, textual, and a subset of JavaScript.'
至于没有抛出错误,那么
var x = { foo: undefined };
x.foo === undefined; // true
var json = JSON.stringify(x);
var y = JSON.parse(json);
y.foo === undefined; // true
因此JSON.stringify
可以创建一个代表值x
的字符串。
在这种情况下,抛出错误不会有用。实际上是JSON.stringify
忽略所有没有JSON表示的值,所以函数
被忽略了。例如,这使得序列化对象数据变得容易。
最后,请记住JSON.stringify采用replacer
函数
一个参数,可用于改变字符串化的发生方式。
因此,要使JSON.stringify
抛出具有undefined
值的现有属性:
var replacer = function(key, value){
if(value === undefined){
throw 'JSON.stringify: bad property: ' + key;
}
return value;
};
var x = {foo: undefined};
JSON.stringify(x, replacer);
// uncaught exception: JSON.stringify: bad property: foo
或者替换为null
:
var replacer = function(key, value){
if(value === undefined){
return null;
}
return value;
};
var x = {foo: undefined};
JSON.stringify(x, replacer); // '{"foo":null}'