如何合并javascript两个对象,但只更新更改的属性

时间:2015-11-25 16:47:05

标签: javascript underscore.js

我正在尝试编写一个函数,让我在下面的示例中更新kitchen。然而,使用像下划线extend这样的东西,当它更新整个fridge物体时,会把冰箱里的啤酒吹走。

我是否可以使用一种简单的方法,以便只使用changeKitchen对象中更改的属性进行更新,而不更新整个fridge对象?

// My original kitchen
var kitchen = {
  fridge: {
    beer: true,
    celery: false
  },
  cabinets: {
    candy: true
  }
};


// updates I would like to make to my kitchen
var changeKitchen = {
  fridge: {
    celery: true
  }
};


var updatedKitchen = _.extend(kitchen, changeKitchen);

console.log(updatedKitchen);

返回

var kitchen = {
  fridge: {
    celery: false // beer is gone
  },
  cabinets: {
    candy: true
  }
};

但我希望:

var kitchen = {
  fridge: {
    beer: true,
    celery: true // changed
  },
  cabinets: {
    candy: true
  }
};

4 个答案:

答案 0 :(得分:3)

由于您已经在使用Underscore,因此您可以使用Lodash代替Underscore的超集,并使用其#merge函数。

请参阅有关Differences between Lodash and underscore

的此问题

// My original kitchen
var kitchen = {
  fridge: {
    beer: true,
    celery: false
  },
  cabinets: {
    candy: true
  }
};


// updates I would like to make to my kitchen
var changeKitchen = {
  fridge: {
    celery: true
  }
};


var updatedKitchen = _.merge(kitchen, changeKitchen);

document.write(JSON.stringify(updatedKitchen));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>

答案 1 :(得分:2)

在嵌套对象上使用_.extend

function update(obj1, obj2) {
  for (var p in obj2) {
    if (obj1[p]) {
        _.extend(obj1[p], obj2[p]);
    } else {
      obj1[p] = obj2[p];
    }
  }
}

update(kitchen, changeKitchen);

DEMO

答案 2 :(得分:1)

以下是普通Javascript的解决方案:

&#13;
&#13;
var kitchen = { fridge: { beer: true, celery: false }, cabinets: { candy: true } },
    changeKitchen = { fridge: { celery: true } };

function update(source, target) {
    Object.keys(target).forEach(function (k) {
        if (typeof target[k] === 'object') {
            source[k] = source[k] || {};
            update(source[k], target[k]);
        } else {
            source[k] = target[k];
        }
    });
}

update(kitchen, changeKitchen);
document.write('<pre>' + JSON.stringify(kitchen, 0, 4) + '</pre>');
&#13;
&#13;
&#13;

答案 3 :(得分:0)

尝试使用for..in循环,Object.keys()

// My original kitchen
var kitchen = {
  fridge: {
    beer: true,
    celery: false
  },
  cabinets: {
    candy: true
  }
};

var changeKitchen = {
  fridge: {
    celery: true
  }
};

for (var prop in changeKitchen) {
  if (kitchen[prop]) {
    kitchen[prop]
      [Object.keys(changeKitchen[prop])] = changeKitchen[prop]
         [Object.keys(changeKitchen[prop])]
  }
}

console.log(kitchen)