JS递归对象分配

时间:2018-04-09 06:32:05

标签: javascript javascript-objects shallow-copy shallow-clone

我了解到在使用Object.assign()时它只扩展了顶级对象。我怎样才能深度扩展对象?例如,让我们说我有以下源对象:

const source = {
  id: 1,
  otherKey: {},
  params: {
    page: {
      a: 1,
      b: {}
    },
    data: {
      b: 1
    }
  }
}

我正在使用这样的Object.assign()

Object.assign({}, source, {
  params: {
    page: {
      a: 2
    }
  }
}

结果将是:

{
      id: 1,
      otherKey: {},
      params: {
        page: {
          a: 2
        }
      }
}

如何以浅克隆方式保留params.data键和params.page.b键。

oldObject.params.data === newObject.params.data  // true
oldObject.params.page === newObject.params.page  // false
oldObject.params.page.b === newObject.params.page.b // true

注意:此问题与How to deep merge instead of shallow merge不同。那里的答案没有给出预期的结果。

选中从上述链接获得答案的bin

1 个答案:

答案 0 :(得分:2)

因此,在您发布的代码中,如果源和目标都包含相同的密钥,则会发生什么。该对象被递归给孩子们。但是,如果您只是将内部块更改为:

if (!target[key]) { 
  Object.assign(target, { [key]: {} });
}else{          
  target[key] = Object.assign({}, target[key])
}
mergeDeep(target[key], source[key]);

这将为源和目标中找到的任何键创建新的已分配对象。有趣的是,如果你这样做,你的预期falseys将不会出现在控制台中。这是因为目标将始终匹配结果,因为它是最终的变异对象。因此,为了获得预期的false结果,您需要执行以下操作:

var tester = source.params
const result = mergeDeep(source, b)
console.log(tester === result.params) // this will be false after the above addition

您可以在此处查看所需结果:http://jsbin.com/vicemiqiqu/1/edit?js,console