How can I merge javascript two objects but only update properties that change

不问归期 提交于 2019-12-24 00:56:32

问题


I'm trying to write a function that will let me update my kitchen in this example below. Using something like underscore's extend, however, blows away the beer in my fridge as it's updating the entire fridge object.

Is there a simple method I can use so that I only make updates with the properties that change in my changeKitchen object and not update the entire fridge object?

// 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);

Returns

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

However I would like to have:

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

回答1:


Since you're already using Underscore, you could use Lodash instead, which is a superset of Underscore, and use its #merge function.

See this question about 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>



回答2:


Use _.extend on the nested objects instead:

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




回答3:


Here is a solution in plain Javascript:

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>');



回答4:


Try using for..in loop , 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)


来源:https://stackoverflow.com/questions/33922030/how-can-i-merge-javascript-two-objects-but-only-update-properties-that-change

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!