调用 JSON.stringify 时检测 parent object
Detecting parent object when calling JSON.stringify
我有一个 object,即:
{
item1: "value1",
item2: "value2",
item3: {
item4: "value4",
item5: "value5"
}
}
我想将 JSON.stringify
与 replacer
函数一起使用,该函数 对项目 4 和 5 的作用不同 ,这是项目 3 的内部属性。
如何做到这一点?
类似于以下内容 pseudo-code:
return JSON.stringify(obj, (key, val) => {
if (key is child of Item3) {
return someOtherValue;
} else {
return val;
}
}
所需的输出是 json。即:
{
"item1" : "value1",
"item2" : "value2",
"item3" : {
"item4" : "theSomeOtherValue",
"item5" : "theSomeOtherValue"
}
编辑:
第 4 项和第 5 项是事先不知道的,它们是动态生成的。
我只在 运行 时间
知道 item3
的标题
这里至少有两种方法可以采用。
replacer函数中,this
是被处理的对象,所以当item4
和item5
被处理时,this
指的是item3
对象。因此,如果有关该对象的任何内容可以让您识别它,您可以通过查看 this
来识别它。 (一定要使用传统函数,而不是箭头函数,这样 JSON.stringify
可以在替换调用期间设置 this
是什么。)
replacer函数是通过处理的key和value调用的,所以如果对象的key("item3"
)是唯一的,看到就可以做特殊处理。
以下是#1 的几个示例:
例如,如果您有对象的引用,您可以将 this
与 obj.item3
进行比较:
const obj = {
item1: "value1",
item2: "value2",
item3: {
item4: "value4",
item5: "value5"
}
};
console.log(JSON.stringify(obj, function(key, value) {
// ^^^^^^^^^−−−−− Traditional function, not arrow function
if (this === obj.item3) {
console.log("do something different, it's " + key);
return "theSomeOtherValue";
}
return value;
}));
如果您没有它的参考资料,您可以使用您拥有的关于它的任何其他识别信息。例如,对于示例数据,您可以看到它具有 item4
和 item5
属性:
console.log(JSON.stringify({
item1: "value1",
item2: "value2",
item3: {
item4: "value4",
item5: "value5"
}
}, function(key, value) {
// ^^^^^^^^^−−−−− Traditional function, not arrow function
if (this.hasOwnProperty("item4") && this.hasOwnProperty("item5")) {
console.log("do something different, it's " + key);
return "theSomeOtherValue";
}
return value;
}));
不过,这只是两个例子;关键是 this
是被字符串化的对象。
这是#2 的示例:
console.log(JSON.stringify({
item1: "value1",
item2: "value2",
item3: {
item4: "value4",
item5: "value5"
}
}, (key, value) => { // It's okay if this one is an arrow function, we're not relying on
// `JSON.stringify` setting `this` for us
if (key === "item3") {
return {
item4: "theSomeOtherValue",
item5: "theSomeOtherValue"
};
}
return value;
}));
如果你需要被处理对象的完整路径,那就比较麻烦了,不过你可以得到:
let paths = new Map();
console.log(JSON.stringify({
item1: "value1",
item2: "value2",
item3: {
item4: "value4",
item5: "value5"
},
item6: {
item3: {
item4: "non-special item4",
item5: "non-special item5"
}
}
}, function(key, value) {
// ^^^^^^^^^−−−−− Traditional function, not arrow function
const path = paths.get(this);
// Special processing for the properties of root.item3
if (path === "root.item3") {
return key === "item4" || key === "item5"
? "theSomeOtherValue"
: value;
}
// Keep track of the path of the object
for (const [k, v] of Object.entries(this)) {
if (typeof v === "object") {
if (path) {
// The regex checks for property names that aren't valid(ish)
// property names so we can use brackets notation
paths.set(v, path + (/^\w+$/.test(k) ? "." + k : `[${JSON.stringify(k)}]`));
} else {
paths.set(v, "root");
}
}
}
return value;
}));
JSON.stringify 接受替换函数作为第二个参数(并提供当前对象被迭代为 this
)所以你可以这样做:
return JSON.stringify(obj, function(key, val) {
if (this === obj.item3) {
return "theSomeOtherValue";
}
return val;
});
实现相同目的的另一种方法(使用当前 key
而不是 this
对象引用):
return JSON.stringify(obj, function(key, val) {
if (key === "item4" || key === "item5") {
return "theSomeOtherValue";
}
return val;
});
您可以将找到的所需对象存储在闭包中,并根据对象更改 return 值。
这种方法有效没有this
。
function replacer(parent) {
let reference = {};
return function (key, val) {
if (key === parent) reference = val;
return key in reference
? '#' + val
: val;
};
}
var obj = { item1: "value1", item2: "value2", item3: { item4: "value4", item5: "value5" } },
json = JSON.stringify(obj, replacer('item3'));
console.log(json);
我有一个 object,即:
{
item1: "value1",
item2: "value2",
item3: {
item4: "value4",
item5: "value5"
}
}
我想将 JSON.stringify
与 replacer
函数一起使用,该函数 对项目 4 和 5 的作用不同 ,这是项目 3 的内部属性。
如何做到这一点?
类似于以下内容 pseudo-code:
return JSON.stringify(obj, (key, val) => {
if (key is child of Item3) {
return someOtherValue;
} else {
return val;
}
}
所需的输出是 json。即:
{
"item1" : "value1",
"item2" : "value2",
"item3" : {
"item4" : "theSomeOtherValue",
"item5" : "theSomeOtherValue"
}
编辑:
第 4 项和第 5 项是事先不知道的,它们是动态生成的。
我只在 运行 时间
item3
的标题
这里至少有两种方法可以采用。
replacer函数中,
this
是被处理的对象,所以当item4
和item5
被处理时,this
指的是item3
对象。因此,如果有关该对象的任何内容可以让您识别它,您可以通过查看this
来识别它。 (一定要使用传统函数,而不是箭头函数,这样JSON.stringify
可以在替换调用期间设置this
是什么。)replacer函数是通过处理的key和value调用的,所以如果对象的key(
"item3"
)是唯一的,看到就可以做特殊处理。
以下是#1 的几个示例:
例如,如果您有对象的引用,您可以将 this
与 obj.item3
进行比较:
const obj = {
item1: "value1",
item2: "value2",
item3: {
item4: "value4",
item5: "value5"
}
};
console.log(JSON.stringify(obj, function(key, value) {
// ^^^^^^^^^−−−−− Traditional function, not arrow function
if (this === obj.item3) {
console.log("do something different, it's " + key);
return "theSomeOtherValue";
}
return value;
}));
如果您没有它的参考资料,您可以使用您拥有的关于它的任何其他识别信息。例如,对于示例数据,您可以看到它具有 item4
和 item5
属性:
console.log(JSON.stringify({
item1: "value1",
item2: "value2",
item3: {
item4: "value4",
item5: "value5"
}
}, function(key, value) {
// ^^^^^^^^^−−−−− Traditional function, not arrow function
if (this.hasOwnProperty("item4") && this.hasOwnProperty("item5")) {
console.log("do something different, it's " + key);
return "theSomeOtherValue";
}
return value;
}));
不过,这只是两个例子;关键是 this
是被字符串化的对象。
这是#2 的示例:
console.log(JSON.stringify({
item1: "value1",
item2: "value2",
item3: {
item4: "value4",
item5: "value5"
}
}, (key, value) => { // It's okay if this one is an arrow function, we're not relying on
// `JSON.stringify` setting `this` for us
if (key === "item3") {
return {
item4: "theSomeOtherValue",
item5: "theSomeOtherValue"
};
}
return value;
}));
如果你需要被处理对象的完整路径,那就比较麻烦了,不过你可以得到:
let paths = new Map();
console.log(JSON.stringify({
item1: "value1",
item2: "value2",
item3: {
item4: "value4",
item5: "value5"
},
item6: {
item3: {
item4: "non-special item4",
item5: "non-special item5"
}
}
}, function(key, value) {
// ^^^^^^^^^−−−−− Traditional function, not arrow function
const path = paths.get(this);
// Special processing for the properties of root.item3
if (path === "root.item3") {
return key === "item4" || key === "item5"
? "theSomeOtherValue"
: value;
}
// Keep track of the path of the object
for (const [k, v] of Object.entries(this)) {
if (typeof v === "object") {
if (path) {
// The regex checks for property names that aren't valid(ish)
// property names so we can use brackets notation
paths.set(v, path + (/^\w+$/.test(k) ? "." + k : `[${JSON.stringify(k)}]`));
} else {
paths.set(v, "root");
}
}
}
return value;
}));
JSON.stringify 接受替换函数作为第二个参数(并提供当前对象被迭代为 this
)所以你可以这样做:
return JSON.stringify(obj, function(key, val) {
if (this === obj.item3) {
return "theSomeOtherValue";
}
return val;
});
实现相同目的的另一种方法(使用当前 key
而不是 this
对象引用):
return JSON.stringify(obj, function(key, val) {
if (key === "item4" || key === "item5") {
return "theSomeOtherValue";
}
return val;
});
您可以将找到的所需对象存储在闭包中,并根据对象更改 return 值。
这种方法有效没有this
。
function replacer(parent) {
let reference = {};
return function (key, val) {
if (key === parent) reference = val;
return key in reference
? '#' + val
: val;
};
}
var obj = { item1: "value1", item2: "value2", item3: { item4: "value4", item5: "value5" } },
json = JSON.stringify(obj, replacer('item3'));
console.log(json);