当使用JSON.stringify
(或类似的东西)串化一个对象时,有没有一种方法可以限制串化深度,即只进入对象树的第n层,然后忽略后面的所有内容(或者更好的方法:在其中放置占位符,表示遗漏了一些东西)?
我知道JSON.stringify
采用function (key, value)
形式的替换函数,但是我没有找到一种方法来获取传递给替换函数的当前键-值对的原始对象的深度。
有没有一种方法可以用默认的JSON.stringify实现做到这一点?或者我已经到了应该自己实现字符串的地步了吗?或者,有没有其他你可以推荐的具有此选项的字符串化库?
发布于 2017-10-24 18:39:28
我想在不包含第三方库/太多代码的情况下,在第一级上对一个对象进行字符串赋值。
如果您正在寻找相同的代码,这里有一个快速的一行程序来完成此操作:
var json = JSON.stringify(obj, function (k, v) { return k && v && typeof v !== "number" ? (Array.isArray(v) ? "[object Array]" : "" + v) : v; });
顶层对象将没有键,所以它总是被简单地返回,但是任何在下一层不是"number“的对象都将被强制转换为一个字符串。数组的特殊情况,否则这些数组会暴露得更多。
如果你不喜欢这种特殊的数组情况,请使用我的旧解决方案,我也改进了它:
var json = JSON.stringify(obj, function (k, v) { return k && v && typeof v !== "number" ? "" + v : v; }); // will expose arrays as strings.
在顶层传递数组而不是对象仍然可以在这两种解决方案中工作。
示例:
var obj = {
keyA: "test",
keyB: undefined,
keyC: 42,
keyD: [12, "test123", undefined]
}
obj.keyD.push(obj);
obj.keyE = obj;
var arr = [12, "test123", undefined];
arr.push(arr);
var f = function (k, v) { return k && v && typeof v !== "number" ? (Array.isArray(v) ? "[object Array]" : "" + v) : v; };
var f2 = function (k, v) { return k && v && typeof v !== "number" ? "" + v : v; };
console.log("object:", JSON.stringify(obj, f));
console.log("array:", JSON.stringify(arr, f));
console.log("");
console.log("with array string cast, so the array gets exposed:");
console.log("object:", JSON.stringify(obj, f2));
console.log("array:", JSON.stringify(arr, f2));
发布于 2019-07-25 09:22:44
下面是一个遵守内置JSON.stringify()
规则的函数,同时也限制了深度:
function stringify(val, depth, replacer, space) {
depth = isNaN(+depth) ? 1 : depth;
function _build(key, val, depth, o, a) { // (JSON.stringify() has it's own rules, which we respect here by using it for property iteration)
return !val || typeof val != 'object' ? val : (a=Array.isArray(val), JSON.stringify(val, function(k,v){ if (a || depth > 0) { if (replacer) v=replacer(k,v); if (!k) return (a=Array.isArray(v),val=v); !o && (o=a?[]:{}); o[k] = _build(k, v, a?depth:depth-1); } }), o||(a?[]:{}));
}
return JSON.stringify(_build('', val, depth), null, space);
}
它的工作原理:
以递归方式调用
_build()
来构建达到请求深度的嵌套对象和数组。JSON.stringify()
用于迭代每个对象的直接属性,以遵守内置规则。‘'undefined’总是从内部替换器返回,所以还没有真正构造JSON。请记住,第一次调用内部替换器时,键是空的(这是在最终结果上调用stringified).JSON.stringify()
的项,以生成实际的JSON。示例:
var value={a:[12,2,{y:3,z:{q:1}}],s:'!',o:{x:1,o2:{y:1}}};
console.log(stringify(value, 0, null, 2));
console.log(stringify(value, 1, null, 2));
console.log(stringify(value, 2, null, 2));
{}
{
"a": [
12,
2,
{}
],
"s": "!",
"o": {}
}
{
"a": [
12,
2,
{
"y": 3,
"z": {}
}
],
"s": "!",
"o": {
"x": 1,
"o2": {}
}
}
(对于处理循环引用的版本,请参阅此处: -包括TypeScript版本)
更新:修复了空数组渲染为空对象的错误。
发布于 2014-04-04 19:22:36
对您的对象进行深度克隆(使用low-dash等库),执行您想做的任何修剪操作,然后将其传递给JSON.stringify。我不会试图重新发明JSON.stringify,那是在错误的地方努力。
编辑看起来有人已经按照你的建议做了:JSON.stringify deep objects
我不推荐这样做,因为原生JSON.stringify总是更快、更健壮
编辑这里是一个似乎可以做你想做的事情的库:http://philogb.github.io/jit/static/v20/Docs/files/Core/Core-js.html#$jit.json.prune
https://stackoverflow.com/questions/16466220
复制相似问题