javascript - 合并两个对象而不覆盖

标签 javascript jquery object merge

我有一个这样的 defaultObject:

var default = {
    abc: "123",
    def: "456",
    ghi: {
       jkl: "789",
       mno: "012"
    }
};

还有一个像:

var values = {
    abc: "zzz",
    ghi: {
       jkl: "yyy",
    }
};

如何将这 2 个对象与以下结果合并(无覆盖)?

var values = {
    abc: "zzz",
    def: "456",
    ghi: {
       jkl: "yyy",
       mno: "012"
    }
};

(我不想更改默认对象!)

最佳答案

对于那些不使用 jQuery 的人,这里有一个 vanilla-js 解决方案。

解决方案:

function extend (target) {
    for(var i=1; i<arguments.length; ++i) {
        var from = arguments[i];
        if(typeof from !== 'object') continue;
        for(var j in from) {
            if(from.hasOwnProperty(j)) {
                target[j] = typeof from[j]==='object'
                ? extend({}, target[j], from[j])
                : from[j];
            }
        }
    }
    return target;
}

压缩(使用 Closure Compiler ):

只有 199 个字符!

var extend=function e(c){for(var d=1;d<arguments.length;++d){var a=arguments[d];if("object"===typeof a)for(var b in a)a.hasOwnProperty(b)&&(c[b]="object"===typeof a[b]?e({},c[b],a[b]):a[b])}return c}

使用方法:

extend(target, obj1, obj2); // returns target

如果只想合并,使用

var merged = extend({}, obj1, obj2);

特点:

  • 它不查看对象的原型(prototype)。
  • 忽略非对象。
  • 它是递归的,以便合并作为对象的属性。
  • target 的属性中引用的对象,如果被扩展,将被新对象替换,并且不会修改原始对象。
  • 在属性名称相同的情况下,合并值将是最后一个(按参数顺序)非对象值之后对象的合并。或者,如果最后一个不是对象,则它本身。

示例:

extend({}, {a:1}, {a:2});            // {a:2}
extend({}, {a:1}, {b:2});            // {a:1, b:2}
extend({}, {a: {b:1}}, {a: {b:2}});  // {a: {b:2}}
extend({}, {a: {b:1}}, {a: {c:2}});  // {a: {b:2, c:2}}
extend({}, {a: {a:1}}, {a: {b:2}}, {a: 'whatever non object'});
    // {a: "whatever non object"}
extend({}, {a: {a:1}}, {a: {b:2}}, {a: 'whatever non object'}, {a: {c:3}},{a: {d:4}});
    // {a: {c:3, d:4}}

警告:

请注意,如果浏览器不够智能,它可能会陷入无限循环:

var obj1={},
    obj2={};
obj1.me=obj1;
obj2.me=obj2;
extend({},obj1,obj2);

如果浏览器足够聪明,它可以抛出一个错误,或者返回 {me: undefined},或者其他什么。

请注意,如果您使用 jQuery 的 $.extend,此警告也适用。

关于javascript - 合并两个对象而不覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20590177/

相关文章:

Javascript:使对象无效时不会删除 setInterval

javascript - 如何过滤对象数组的子对象,然后返回带有更新后的子对象的父对象?

javascript - 如何根据另一个对象数组对一个对象数组进行排序

javascript - Jquery Mobile 返回按钮滚动到顶部

javascript - RadTabStrip - 隐藏选项卡客户端

php - 如何在 PHP 中释放内存?

javascript - 检查元素是否在数组中

JavaScript 仅通过 messageid 将对象创建为数组

javascript - 控制 ENTER 键

c++ - 在 C++ 中创建一个全局对象数组