有没有办法只获得下面的浅层副本才能获得一层深度?我有办法使用完全不同的设计解决这个问题,但我想知道是否有其他人遇到过我之前想要转换为字符串的内容。
var SomeObjClass = function() {
var self = this;
this.group = {
members: [self]
};
};
var p = new SomeObjClass();
var str = JSON.stringify(p);
答案 0 :(得分:2)
有点不清楚你在问什么,但如果你的目标是简单地将圆形对象字符串化,那么你必须覆盖toJSON
以指明你的方式。 d喜欢你的对象代表
function SomeObjClass () {
var self = this;
this.group = {
members: [self]
};
}
SomeObjClass.prototype.addMember = function(m) {
this.group.members.push(m);
};
// when stringifying this object, don't include `self` in group.members
SomeObjClass.prototype.toJSON = function() {
var self = this;
return {
group: {
members: self.group.members.filter(function (x) {
return x !== self
})
}
};
}
var a = new SomeObjClass();
var b = new SomeObjClass();
a.addMember(b);
console.log(JSON.stringify(a))

如果没有看到更多代码,这可能是最好的帮助。我不知道您是如何使用此代码的,但无论如何,这可能不是您班级的最佳设计。如果您共享该类的其余部分以及使用它的代码,我们可以更有效地帮助您。
答案 1 :(得分:0)
如果您查看有关JSON.stringify的MDN参考,您会看到它接受replacer
函数作为第二个参数。此功能可用于按摩您想要字符串化的元素。
它可以帮助您避免循环问题。
例如:
function avoidCircularReference(obj) {
return function(key, value) {
return key && typeof value === 'object' && obj === value ? undefined : value;
};
}
var SomeObjClass = function() {
var self = this;
this.group = {
members: [self, {a:'f', b: [self]}]
};
};
var p = new SomeObjClass();
var str = JSON.stringify(p, avoidCircularReference(p));
console.log(str);
然而,正如文档中所述,并显示了运行示例:
注意:您无法使用replacer函数从数组中删除值。如果返回undefined或函数,则使用null。
所以你必须以某种方式处理这些空值。无论如何,你可以使用这个功能并“适应”你的需要。例如,并应用于您的示例:
function avoidCircularReference(obj) {
var removeMeFromArray = function(arr) {
var index = arr.indexOf(obj);
if (index > -1) {
arr.splice(index, 1);
}
};
return function(key, value) {
if (Object.prototype.toString.call(value) === "[object Array]") {
removeMeFromArray(value);
}
return value;
};
}
var SomeObjClass = function() {
var self = this;
this.group = {
members: [self, {
a: 'f',
b: [self]
}]
};
};
var p = new SomeObjClass();
var str = JSON.stringify(p, avoidCircularReference(p));
console.log(str);
答案 2 :(得分:0)
要解决问题并保持JSON.stringify
简单,我使用以下方法(在我的脱水方法中)
public dehydrate(): string {
var seenObjects = [];
function inspectElement(key, value) {
if (detectCycle(value)) {
return '[Ciclical]';
} else {
return value;
};
};
function detectCycle(obj): boolean {
if (obj && (typeof obj == 'object')) {
for (let r of seenObjects) {
if (r == obj) {
return true;
};
};
seenObjects.push(obj);
};
return false;
};
let json: string = JSON.stringify(this, inspectElement,' ');
return json;
};
请注意,虽然这是TypeScript,但使用强类型来实现方法内部的结果会让我们感到困惑。
不幸的是,我不得不使用for
而不是数组搜索,因为它根本不适用于我。
答案 3 :(得分:0)
这是对我有用的实现。它依靠引用比较来实现相等性,为此目的应该很好。
我将有问题的对象的索引包括在替换器的返回值中,以便原则上可以在反序列化时恢复循环对象。
function safeJsonStringify(value) {
const visitedObjs = [];
function replacerFn(key, obj) {
const refIndex = visitedObjs.indexOf(obj);
if (refIndex >= 0) return `cyclic-ref:${refIndex}`;
if (typeof obj === 'object' && obj !== null) visitedObjs.push(obj);
return obj;
}
return JSON.stringify(value, replacerFn);
}
// Take it for a spin:
const cyclic = { greeting: 'Hello!' };
cyclic.badRef = cyclic;
console.log(safeJsonStringify(cyclic));