这是我的代码:
BAD = {
"a": "2",
"b": 1,
"c": "Nexus",
"d": "Alligator",
"e": 5,
"f": 1431807036,
"g": {
"2": {
"w": 17,
"b": 5
}
}
}
console.log(JSON.stringify(BAD, ['a', 'b', 'c', 'd', 'e', 'g']));
http://jsfiddle.net/whv7x6xc/1/
密钥a
,b
,c
,d
,e
和g
是唯一被字符串化的密钥,但有一个问题。它忽略了分配给g
的对象。
但是,如果你这样做:console.log(JSON.stringify(BAD));
它会显示正确的字符串化版本。
编辑:w
和b
并且动态并定期更改(来来去去),所以我不能只是对它们进行硬编码。
答案 0 :(得分:6)
JSON替换器是递归的。这意味着它为所遇到的所有对象使用相同的数组。换句话说,它使用相同的值来映射BAD.g
的值。由于Bad.g
的值没有与您提供的键匹配的任何键,因此无法正确映射任何内容。这意味着我们必须添加" 2"你的阵列。现在" 2"还有一个具有不同键的对象。我们已经考虑了" b",所以现在我们只需要添加" w"你的阵列。
在为替换者提供数组时,最好将数组视为所有要映射的键的列表。
DEMO:http://jsfiddle.net/dirtyd77/whv7x6xc/4/
console.log(JSON.stringify(BAD, ['a', 'b', 'c', 'd', 'e', 'g', '2', 'w']));
希望这有帮助,如果您有任何问题,请与我联系。
以下是documentation,
的摘录如果返回任何其他对象,则会以递归方式将对象字符串化为JSON字符串,并在每个属性上调用replacer函数,除非该对象是函数,在这种情况下,不会向JSON字符串添加任何内容。
对于动态键,您始终可以创建一个函数来推送到数组并将该数组用于白名单。这是一个例子:
DEMO:http://jsfiddle.net/dirtyd77/whv7x6xc/5/
var BAD = {
"a": "2",
"b": 1,
"c": "Nexus",
"d": "Alligator",
"e": 5,
"f": 1431807036,
"g": {
"2": {
"w": 17,
"b": 5
}
}
}
var whitelist = [];
iterate(BAD);
console.log(whitelist, JSON.stringify(BAD, whitelist));
function iterate(obj){
for(var key in obj){
// may have to do some checking to ignore any keys you don't care about
whitelist.push(key);
// if value is an object, will use this same function to push to whitelist array
if(typeof obj[key] === 'object'){
return iterate(obj[key]);
}
}
}
您也可以使用现有的whitelist
,只需在g
密钥上附加密钥(假设动态不是这样):
DEMO:http://jsfiddle.net/dirtyd77/whv7x6xc/6/
var whitelist = ['a', 'b', 'c', 'd', 'e', 'g'];
iterate(BAD.g);
console.log(whitelist, JSON.stringify(BAD, whitelist));
function iterate(obj){
for(var key in obj){
whitelist.push(key);
if(typeof obj[key] === 'object'){
return iterate(obj[key]);
}
}
}
答案 1 :(得分:4)
replacer
参数很深,因为它会影响所有属性的字符串化,即使它们不在第一级。如果您将"2"
添加到数组中,则会看到该对象已字符串化,减去"w"
,因为"w"
未被替换者列入白名单。
JSON.stringify(BAD, ['a', 'b', 'c', 'd', 'e', 'g', '2'])
考虑使用replacer
的原因。如果你使用黑名单而不是白名单,你可能会通过传入函数而不是数组来提供更好的服务。
JSON.stringify(BAD, function replacer(key, value) {
var blacklist = ['b', 'g']
return blacklist.indexOf(key) === -1 ? value : undefined
})
答案 2 :(得分:2)