我有几个JS对象。它们可以具有任何结构:
{
name: "first",
_ref_id: 1234,
spec: {
_ref_id: 2345,
data: "lots of data"
}
}
{
name: 'second',
_ref_id: 5678,
container: {
_ref_id: 6789,
children: [
{_ref_id: 3214, name: 'Bob'}
{_ref_id: 1111, name: 'Mark'}
{_ref_id: 2222, name: 'Frank'}
]
}
}
问题:
我需要制作此对象的副本,但使用不同的_ref_ids。
创建"第一个"对象我看起来像这样:
first = {
name: "first",
_ref_id: uuid.v4(),
spec: {
_ref_id: uuid.v4(),
data: "lots of data"
}
}
因此,当我创建对象时,我知道对象的结构,但是在链的下游,我试图复制这个对象,我无法访问,我不知道这个对象的结构是什么,我所拥有的只是它自己的对象。因此,在应对"第一次"之后,我希望:
{
name: "first",
_ref_id: 8888,
spec: {
_ref_id: 9999,
data: "lots of data"
}
}
我尝试在对象创建过程中不定义_ref_id一个简单的值,而是一种记忆函数:
refId(memoized = true){
var memo = {}
return () => {
if(!memoized) memo = {}
if(memo['_ref_id'])
return memo._ref_id
else {
memo._ref_id = uuid.v4()
return memo._ref_id
}
}
}
所以我可以创建它:
first = {
name: "first",
_ref_id: refId(),
spec: {
_ref_id: refId(),
data: "lots of data"
}
}
并在我尝试访问它的值时将first._ref_id更改为 first._ref_id((。
但是我不知道如何从应对函数内部重置记忆变量,或者这是否可能?
有没有人遇到过类似的问题?也许有不同的方法可以解决它?
附注:
我在这个项目中使用了 lodash 和不可变.js但我还没有找到任何用于此特定任务的辅助函数。
灵感来自 克隆JS对象的最优雅方式,检查_ref_id
字段:
function deepCopyWithNewRefId(obj) {
if (null == obj || "object" != typeof obj) return obj;
var copy = obj.constructor();
for (var attr in obj) {
if (obj.hasOwnProperty(attr)) {
if (attr == "_ref_id") {
copy[attr] = uuid.v4();
} else {
copy[attr] = deepCopyWithNewRefId(obj[attr]);
}
}
}
return copy;
}
其使用日志:
var uuid = { v4 : function(){ return Math.random()} };
var first = {
name: "first",
_ref_id: uuid.v4(),
spec: {
_ref_id: uuid.v4(),
data: "lots of data"
}
};
console.log(first._ref_id);
console.log(first.spec._ref_id);
var second = deepCopyWithNewRefId(first);
console.log(second);
console.log(second._ref_id);
console.log(second.spec._ref_id);
// the printed values are not the same. The rest of the object is