使用不同的密钥将一个项目替换为另一个项目时克隆对象的惯用 ES6/ESnext 方法?

Idiomatic ES6/ESnext way to clone an object while replacing one item with another using a different key?

如果我想在替换添加新项目或使用相同的密钥用新项目替换项目时对对象进行浅克隆而不改变,我知道我可以使用 Object.assign()

const oldOb = { foo:10, bar:20 };
const newOb = Object.assign({}, oldOb, { bar:100 });

但是如果我想用 baz:50 替换 bar:20 呢?

我知道我可以使用 delete ob[bar] 但这是突变,我想避免。

是否有一种简洁的函数式编程方法可以使用较新的 ES6/ES7/Babel 功能实现此目的?

As mentioned by @FelixKling in the comments, just using delete obj.key on an already cloned object would be the simplest solution and is perfectly fine regarding the concept of immutability.

但是如果您想要更多 "complex" 的解决方案,您可以使用 destructuring 克隆对象并删除所需的 属性.

const l = console.log;

function remove(o, p) {
  const { [p]: undefined, ...props } = o;
  return props;
}

const obj = { someProp: 'someValue', originalProperty: 'originalValue' };

l('remove:\n', remove(obj, 'originalProperty'));
l('original object: \n', obj);

如果您希望通过一种方法同时拥有 replacerenameremove 功能,那么您可以选择以下方法:

const l = console.log;

function replace(o, p, n, v = o[p]) {
  const { [p]: undefined, ...props } = { ...o, ...(n ? { [n]: v } : {}) };
  return props;
}

const obj = { someProp: 'someValue', originalProperty: 'originalValue' };

l('replace:\n', replace(obj, 'originalProperty', 'replacedProperty', 'replacedValue'));
l('rename:\n', replace(obj, 'originalProperty', 'replacedProperty'));
l('remove:\n', replace(obj, 'originalProperty'));
l('original object:\n', obj);

为了更好地理解 replace 函数的较长版本:

function replace(
    obj,
    currentProperty,
    newProperty,
    newPropertyValue = obj[currentProperty]
  ) {
  let replacementObject = {};
  if(newProperty) {
    replacementObject = { [newProperty]: newPropertyValue };
  }
  const { [currentProperty]: undefined, ...remainingProperties } = Object.assign({}, obj, replacementObject);
  return remainingProperties;
}