lodash的深层对象扩展行为

时间:2019-07-17 21:19:17

标签: javascript object lodash

带有以下内容

    var a = {
        a: 0,
        b: [],
        c: "",
        d: { "x": "y", "g": "f" },
        e: {},
        f: function () { return undefined; }(),
        g: false
    };
    var b = {
        a: { "a": "b" },
        b: { "c": "d" },
        c: { "e": "f" },
        d: { "g": "h" },
        e: { "i": "j" },
        f: {},
        g: { "m": "n" },
    };

如果您查看数据类型,我会发现一些虚假或空虚的版本(或近似):数字,数组,字符串,对象,未定义,布尔值。

将以上内容与以下内容配合使用:

    var assinged = _.assign({}, a, b);
    var merged = _.merge({}, a, b);
    var extended = _.extend({}, a, b);

我得到:

  

已分配:

{
    "a": {"a": "b"},
    "b": {"c": "d"},
    "c": {"e": "f"},
    "d": {"g": "h"},
    "e": {"i": "j"},
    "g": {"m": "n"}
}
  

合并:

{
    "a":{"a":"b"},
    "b":[],
    "c":{"e":"f"},
    "d":{"x":"y","g":"h"},
    "e":{"i":"j"},
    "g":{"m":"n"}
}
  

扩展:

{
    "a": {"a": "b"},
    "b": {"c": "d"},
    "c": {"e": "f"},
    "d": {"g": "h"},
    "e": {"i": "j"},
    "g": {"m": "n"}
}
在本示例中,

SO,分配和扩展等效。合并与我想要的最接近-您查看键d,可以看到保留了我现有的键,并且扩展了对象。但是,查看一下b键,您会看到空数组正在用Merge覆盖对象。

两个问题:

  1. lodash中是否有一个简单的命令可以实现我想要的(真正的,完整的深度合并,其中第一个对象中的所有属性都被第二个对象中的值覆盖或扩展)?

  2. _.merge在这里做出了什么选择,导致这种情况发生?

1 个答案:

答案 0 :(得分:3)

  

但是,查看b键,您会看到空数组是   用合并覆盖对象

不覆盖,不可以。

运行_.merge({}, a, b).b时,会得到一个空数组,其c属性设置为"d"。它将数组像对象一样对待,并有效地做到了:

var b = [];
b.c = "d";

// inspect what b is now
console.log(b.length); //=> 0
console.log(b.c); //=> "d"

在javascript中,数组实际上是一个使用整数键表示许多值的对象:

var a = [1,2,3];
a.b = "c";
console.log(Object.keys(a)); //=> ["0", "1", "2", "b"]

您可以在数组上甚至在JavaScript中创建函数,因为它们的行为就像标准对象一样。

因此,是的,它完全按照其应有的方式将对象b的属性合并到对象a中。


您可能希望自己编写自己的自定义合并行为。这个问题可能会对您有所帮助:

How to deep merge instead of shallow merge?