繁体   English   中英

javaScript:使用JSON.parse解析字符串化对象会删除引用

[英]javaScript: Parsing a stringified object with JSON.parse removes references

我试图深度克隆一个对象,用k = JSON.parse(JSON.stringify(a))说“a”。 我使用stringify方式很重要,因为我试图将对象保存到文件中然后从中加载。

我偶然发现了克隆对象的引用问题,如下所示:

 var obj={}; obj.importantProperty={s:2}; obj.c=obj.importantProperty; obj.d=obj.importantProperty; console.log( obj.c === obj.d ); // Returns true var cloned = JSON.parse(JSON.stringify(obj)); console.log( cloned.c === cloned.d ); // Returns false 
我需要在使用JSON.parse时保留引用,在上面的示例中它们不是。 在我的项目中,对象要复杂得多,但最后归结为上面的例子。

在此先感谢任何帮助我的人:)

做这样的事情的正确方法是分别存储公共引用对象并通过ID引用它。

例如,您可以将importantProperty对象保存在数组中,并使用索引作为ID:

var importantProperties = [
  { s: 1 },
  { s: 2 },
  { s: 3 }
];

var obj = {};
obj.importantProperty = importantProperties[1];
obj.c = obj.importantProperty;
obj.d = obj.importantProperty;

然后,当您对对象进行字符串化时,将其引用的对象替换为其索引:

var stringified = JSON.stringify(obj, function(key, value) {
  if (key) {
    return importantProperties.indexOf(value);
  }
  return value;
});
console.log(stringified);
// prints {"importantProperty":1,"c":1,"d":1}

然后,当您解析时,只需反转该过程即可恢复引用:

var parsed = JSON.parse(stringified, function(key, value) {
  if (key) {
    return importantProperties[value];
  }
  return value;
});
console.log(parsed.c === parsed.d && parsed.d === parsed.importantProperty);
// prints true

现在,上面的示例适用于您的示例代码,前提是obj中的所有属性都是来自importantProperties数组的对象。 如果不是这种情况并且只有某些属性是一个importantProperties属性对象,则需要在更换/恢复时检查它。
假设只有“importantProperty”,“c”和“d”属性是这样的对象:
if (['importantProperty', 'c', 'd'].includes(key))而不是if (key)

如果这不够好并且您不希望属性名称与值是否为importantProperties对象有任何关系,则需要在值中与标识符一起指明。 以下是如何完成此操作的示例:

// Replacing
JSON.stringify(obj, function(k, value) {
  if (importantProperties.includes(value)) {
    return 'ImportantProperty['
      + importantProperties.indexOf(value)
      + ']';
  }
  return value;
});

// Reviving
JSON.parse(stringified, function(k, value) {
  if (/^ImportantProperty\[\d+\]$/.test(value)) {
    var index = Number( value.match(/\d+/)[0] );
    return importantProperties[index];
  }
  return value;
});

使用JSON无法实现所需的结果,因为JSON格式只能包含有限的数据类型( http://json.org/ ),当您将对象字符串化为JSON时,某些信息会丢失。

可能还有一些其他类型的序列化技术,但我建议你寻找另一种存储数据的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM