【问题标题】:Shallow copy JavaScript object without references没有引用的浅拷贝 JavaScript 对象
【发布时间】:2019-09-04 11:35:43
【问题描述】:

我怎样才能浅层地复制 JavaScript 对象并删除所有非原始值(所有引用),同时保留给定对象的所有属性。在这个过程中,属性的值可能会变成null

Object.assign、lodash clone 和扩展运算符允许我们获取对象的浅表副本。然而,尽管命名,结果对象并不浅[事实]。它也复制了所有引用,因此仍然可以访问整个对象树。

对于分析解决方案,我需要摆脱比一层更深的东西。

如何在不编写数十条规则来处理所有可能的数据类型的情况下做到这一点(库也可以,ES6 也可以)?理想情况下,对象和数组属性不会丢失,而是替换为某些东西,例如null 或空对象/数组。

示例

const source = {
    nr: 1,
    str: 'ok',
    obj: {
        uhOh: 'kill me'
    },
    arr: ['well ok', { uhOh: 'uhOh' }],
}

// apply voodoo 

const expected = {
    nr: 1,
    str: 'ok',
    obj: {},
    arr: [],
}

// This would also be an valid result:
const expected = {
    nr: 1,
    str: 'ok',
    obj: null,
    arr: null,
}

【问题讨论】:

  • “它也复制了所有引用” - 这就是浅的意思!如果它很深,它将复制被引用的对象,然后引用新对象。
  • 函数被认为是更深层次的对象,还是应该按原样复制函数?
  • 您的第二个有效结果是Is there a proper way to clone certain primitive properties of an object in JavaScript?,并为if (!(source[key] instanceof Object)) { 添加else 块和target[key] = null
  • 我没有投票赞成关闭。但我能理解。问题应该——特别是如果部分问题已经在其他问题中得到回答——是关于问题的特定部分的。否则,您可能会遇到诸如for .. inObject.keys、... 或typeof source[key] === 'object'typeof source[key] instanceof Object 之类的子问题的多种排列,每种排列各有利弊。如果其他问题之一现在为您的子问题之一提出了更好的解决方案,则它不会反映在您的问题的答案中,从而导致混乱。
  • 但是当您寻找替代自己编写的方法时,我也可以理解您的观点。但是,链接到已经存在的类似问题总是一个好主意,展示您拥有的简单解决方案并询问是否有语言功能可以让您以更优雅的方式解决该问题。但问题是这是否更适合代码审查堆栈交换。

标签: javascript


【解决方案1】:

您可以使用for...in 循环访问对象的键。如果值是一个对象,则将expected中的key设置为null,否则将expected中的值设置为source中的值

const source = {
  nr: 1,
  str: 'ok',
  obj: {
    uhOh: 'kill me'
  },
  arr: ['well ok', {
    uhOh: 'uhOh'
  }],
}

const expected = {};

for (const key in source) {
  if (typeof source[key] === 'object')
    expected[key] = null
  else
    expected[key] = source[key]
}

console.log(expected)

【讨论】:

    【解决方案2】:

    这本身不是一个答案,而是@adiga 出色答案的附录,这次使用的是打字稿和类型参数:

    private primitiveClone<T>(source: T): T {
        const dto = Object.assign({}, source);
        for (const key in dto) {
            if (typeof dto[key] === 'object') {
                dto[key] = null;
            }
        }
        return dto;
    }
    

    用法

    var simpleClone = primitiveClone(data);
    

    【讨论】:

      猜你喜欢
      • 2017-08-30
      • 2015-08-28
      • 2017-03-19
      • 1970-01-01
      • 2020-11-07
      • 2012-01-29
      • 1970-01-01
      • 1970-01-01
      • 2012-04-12
      相关资源
      最近更新 更多