字符串化一个循环引用对象的浅拷贝
JavaScript: Stringify a shallow copy of a circular referenced object?
是否有一种方法可以得到下面的浅拷贝,只得到一层深?我有一种方法来解决这个问题,使用一个完全不同的设计,但我想知道是否有人遇到了我之前试图转换成字符串的东西。
var SomeObjClass = function() {
var self = this;
this.group = {
members: [self]
};
};
var p = new SomeObjClass();
var str = JSON.stringify(p);
这有点不清楚你在问什么,但如果你的目标是简单地字符串化一个圆形对象,你必须重写toJSON
来指定你希望你的对象如何表示
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))
这可能是我能在不看到更多代码的情况下帮助你的最好的了。我不知道您是如何使用这些代码的,但无论如何,这可能不是您的类的最佳设计。如果您共享类的其余部分和使用它的代码,我们可能可以更有效地帮助您。
如果您检查关于JSON的MDN引用。stringify,您将看到它接受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);
为了解决问题并保持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
而不是数组搜索,因为它根本不适合我。
这是一个为我工作的实现。它依赖于相等的引用比较,这对于这个目的来说应该是好的。
我在替换器返回值中包含了违规对象的索引,因此原则上,您可以在反序列化时恢复循环对象。
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));
相关文章:
- 如何处理javascript中的循环引用,类似于Excel提供迭代限制的方式
- 装饰$errorProvider时的循环引用
- 使用javascript点击事件的循环引用
- 使用 jQuery 将 HTML 文本抓取到 JSON 中,但由于循环引用而无法字符串化
- 为什么jQuery's每个循环的函数都保存对元素对象的引用
- 为什么$().map生成循环引用
- 如何避免在将索引作为函数的参数发送时引用for循环中的最后一个索引
- 这是否在javascript中创建循环引用
- JS - 数字循环引用
- 如何在 JavaScript 和浏览器中处理循环引用
- 可观察量相互依赖以获取自己的值 - 循环引用
- 循环引用似乎在事件处理程序函数中不起作用
- 循环中的 Javascript 引用:“未捕获的类型错误:无法读取未定义的属性'值'”
- 对于循环错误:未捕获的引用错误,未定义变量.怎么了
- 在子对象中创建对父对象的引用是否会导致循环关系
- HTML5 样板和循环渲染路径/引用脚本和样式
- 如何在jQuery事件中引用循环元素
- 关闭选项卡时Javascript引用循环
- JavaScript/GSON:通过对象图动态访问JSON引用(循环引用)
- Javascript引用循环跳转到第一个结束后