复制 JS 对象可以更改给定键的出现次数

  • 本文关键字:对象 JS 复制 javascript
  • 更新时间 :
  • 英文 :


我有几个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

最新更新