JSBin链接,以便您可以快速运行代码。
问题出现在评论中,但是从文档中说明了reviver(该名称是如何可怕的)如何工作,如果你没有返回一个值或者你返回undefined
那么该属性应该是从对象中删除。如果返回未转换的值,则保持不变。
然而,当我测试它时,看起来整个对象都被移除了。第一个例子工作正常,偶数转换为负数,奇数不变。
但在第二个例子中,我甚至没有得到一个对象,只是未定义。我是误读文档还是其他错误?
结果在第二个例子中未定义。
var obj = {
one: 1,
innerObj: {
two: 2,
four: 4
},
two: 2,
three: 3,
four: 4
},
b = {},
json = JSON.stringify(obj);
/**
* This works as expected.
*/
b = JSON.parse(json, function (name, value) {
if (value % 2 === 0) {
return -value;
}
return value;
});
console.log(b);
/**
[object Object] {
four: -4,
innerObj: [object Object] {
four: -4,
two: -2
},
one: 1,
three: 3,
two: -2
}
*/
obj = {
one: 1,
innerObj: {
two: 2,
four: 4
},
two: 2,
three: 3,
four: 4
};
b = {};
json = JSON.stringify(obj);
/**
* This does not work as expected, instead of deleting the property on the object, the entire object returns undefined.
*/
b = JSON.parse(json, function (name, value) {
if (value % 2 === 0) {
return -value;
}
});
console.log(b);
// undefined
答案 0 :(得分:1)
您的第二个示例已关闭return value;
。
但即使你做到了这一点,它应该只删除返回undefined
作为值的属性,我认为你发现了一个错误(可能是?)。
来自MDN
JSON.parse
examples之一,当调用""
时,它表示最后一个密钥为JSON.parse
我设法使用undefined
错误重现您的代码,似乎如果您返回""
键的值,例如
if (name == "") {
return value;
}
它似乎按预期工作。
obj = {
one: 1,
innerObj: {
two: 2,
four: 4
},
two: 2,
three: 3,
four: 4
};
b = {};
json = JSON.stringify(obj);
/**
* This does not work as expected, instead of deleting the property on the object, the entire object returns undefined.
*/
b = JSON.parse(json, function (name, value) {
if (value % 2 === 0) {
return -value;
}
if (name == "") {
return value;
}
});
console.log(b);
// { two: -2, four: -4 }
编辑:
所以,阅读ECAMScript JSON.parse(text [, reviver]) specification,似乎这是预期的行为。当它描述调用reviver
函数的行为时,调用所有DefineOwnProperty
项后的最后一步是
返回调用抽象操作Walk的结果,传递root和空字符串。
所以,当你没有在你的reviver函数中返回''
名称的值时,它会理解它应该删除它,它代表要返回的整个对象,导致它为{{ 1}}用于undefined
返回。
这解释了MDN文档的关注点
确保按原样返回所有未转换的值
但我同意应该更明确地说明这些小细微差别是如何运作的。