首页 > 解决方案 > 使用 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"}
}

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

两个问题:

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

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

标签: javascriptobjectlodash

解决方案


但是,查看b键,您可以看到空数组正在使用 Merge 覆盖对象

不覆盖,不。

运行时,_.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


您可能需要自己编写的更自定义的合并行为。这个问题可能有助于这项工作:

如何深度合并而不是浅合并?


推荐阅读