Replace object value without replacing reference

/**
 * Method to deep update the values of the source object from new object without changing source  object reference
 *
 * @export
 * @param {*} sourceObj
 * @param {*} newObj
 */
export function updateObjKeepingRef(sourceObj: any, newObj: any): void {
  Object.keys(newObj).forEach(key => {
    // if value is object and instance is not Date
    if (newObj[key] && typeof newObj[key] === 'object' && sourceObj[key] && !(newObj[key] instanceof Date)) {
      updateObjKeepingRef(sourceObj[key], newObj[key]);
    } else {
      // updating properties
      sourceObj[key] = newObj[key];
    }
  });
}

delete everything from the old object, and then add new properties, key-by-key:

function modify(obj, newObj) {

  Object.keys(obj).forEach(function(key) {
    delete obj[key];
  });

  Object.keys(newObj).forEach(function(key) {
    obj[key] = newObj[key];
  });
  
}

var x = {a:1}
modify(x, {b:42})
document.write(JSON.stringify(x));

If you're wondering whether it's a good idea in general, the answer is no. Construct a new object, return it from the function and assign - this is a much preferred way.


You can achieve this (not exactly what you want) if you wrap your object and change the modify function like this,

var wrapper = {};
wrapper.x = {a:1};
function modify(obj, key) {
    obj[key] = {b:2};
}
modify(wrapper, 'x');
console.log(wrapper.x); // {b:2}