如何在JavaScript中最好地比较两个多级对象以找到差异?

3

我有一个JavaScript函数,用于获取一个对象并具有预创建的对象。目标是使函数将传递对象的所有缺少属性添加到预创建的对象中。

仅比较一级时,这很容易。例如,为了实现以下内容:

Precreated: {hello: "world"}  
Passed: {hello: "there", colour: "green"}
Result: {hello: "world", colour: "green"}

你只需要查看传递对象的每个键,查看该键是否已存在于预先创建的对象中,如果不存在,则将其添加到相应的值。
但是,如果你想在多个级别上执行此操作,它会变得有点奇怪。例如,我希望这样运行:
Precreated: {hello: {there: true}}
Passed: {hello: {world: true}}
Result: {hello: {there: true, world: true}}

我的想法是,我将只循环传递的对象,如果我发现其中有一个对象,就调用该对象的函数,依此类推,直到函数处理完所有子级。但是,当你这样做时,你必须动态比较两个对象的子级。比如说,我知道程序有多少层深度,叫什么名字等等,我如何以编程方式访问它?我问这个问题是因为我不能硬编码像if (result[key1][key2][key3]...这样的东西,而且像if (result[keys.join(..)]...这样的东西也不可能。那么,在编写代码时不知道有多少层深度的对象的属性如何以编程方式访问?

1
使用递归。 - Mahi
2
可能是JavaScript对象比较的重复问题。 - baao
1
可能是如何确定两个JavaScript对象的相等性?的重复。 - ChatterOne
@baao 我不只是想比较对象,我想找到并存储差异。 - Zocker3333
2个回答

1

这篇已存在的回答提到了@4castle所提及的帖子,应该正是您想要的:https://dev59.com/p14c5IYBdhLWcg3wa52M#34749873

我的想法是,我将只循环传递的对象,并且如果我在对象内找到一个对象,则再次调用该函数处理该对象,直到所有子项都被该函数处理。

您已经想出要使用递归,这很好。JavaScript允许您使用for ... in循环反映对象的键。您只需要确保您想要复制的对象确实是一个对象而不仅仅是一个值。

我链接的答案使用了他们自己的isObject来完成这个任务。使用Object.assign进行递归地填充对象。


0
你可以使用 for..of 循环,Object.keys() 来检查传递对象的属性是否为对象,如果是,则使用原始对象、传递对象和传递对象的键作为参数递归调用函数,然后将属性分配给原始对象;否则,检查原始对象中是否不存在该属性,如果是,则将传递的属性分配给原始对象。

var precreated1 = {
  hello: {
    there: true
  }
};

var precreated2 = {
  hello: "world"
};

function addProps(props, obj, key) {
  for (let prop of Object.keys(props)) {
    if (Object.getPrototypeOf(props[prop]) === Object.prototype) {
      addProps(props[prop], obj, prop)
    } else {
      if (key) {
        obj[key][prop] = props[prop]
      } else {
        if (!(prop in obj)) {
          obj[prop] = props[prop]
        }
      }
    }
  }
}

addProps({
  hello: {
    world: true
  }
}, precreated1);

console.log("precreated1:", precreated1);

addProps({
  hello: "there",
  colour: "green"
}, precreated2);

console.log("precreated2:", precreated2);


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接