JavaScript Object.assign 的逆

问题描述 投票:0回答:3

我有一个名为

dictionary
的平面 JavaScript 对象,我想根据其他平面对象进行更新。有时我想将对象的每个属性添加到
dictionary
中,有时我想删除
dictionary
中存在于另一个对象中的每个键。稍后我将使用这些属性的值,但为了管理
dictionary
,我只关心它们的名称。

this问题,我知道如何合并属性(例如,使用

Object.assign
)。我怎样才能做相反的事情呢?
Object.unassign
不存在,但是有类似的吗?

例如:

dictionary = { foo: 'bar', baz: 'qux' };
object1 = { spam: 'spam' };

Object.assign(dictionary, object1); // dictionary now has properties: foo, baz, spam

object2 = { foo: 'spam', baz: 'qux' };

Object.unassign(dictionary, object2); // dictionary is now only { spam: 'spam' }
javascript javascript-objects
3个回答
8
投票

没有这样的内置函数,但是编写自己的函数来完成类似的事情是非常简单的:

const dictionary = { foo: 'bar', baz: 'qux' };
const object1 = { spam: 'spam' };
const object2 = { foo: 'spam', baz: 'qux' };

Object.assign(dictionary, object1);

const unassign = (target, source) => {
  Object.keys(source).forEach(key => {
    delete target[key];
  });
};
unassign(dictionary, object2);
console.log(dictionary);

(虽然你可以更改

Object.prototype
并向其中添加这个
unassign
函数,但改变内置对象是非常不好的做法 - 最好制作一个独立的函数)


1
投票

我发现的另一个美丽的方法是通过对象解构......

const dictionary = { foo: 'bar', baz: 'qux', spam: 'spam' };
const {foo, baz, ...newDictionary} = dictionary;
console.log(newDictionary) // { spam: 'spam' }


0
投票

接受的答案中的

unassign
函数缺少
Object.assign
中存在的 3 个方面:

  1. Object.assign
    接受 1 个
    target
    参数和 N 个
    source
    参数,但
    unassign
    接受 1 个
    target
    参数和 1 个
    source
    参数。
  2. Object.assign
    分配任意深度的嵌套对象,但
    unassign
    仅在深度 = 1 时取消分配对象。
  3. Object.assign
    返回
    target
    对象,但
    unassign
    不返回任何内容。

以下函数支持这三个缺失的方面:

function unassign(target, ...sources) {
  for (let source of sources) {
    for (let id in source) {
      const targetValue = target[id];
      if (targetValue) {
        const sourceValue = source[id];
        if (sourceValue !== null && typeof sourceValue === "object" && !Array.isArray(sourceValue) && typeof targetValue === "object" && !Array.isArray(targetValue))
          unassign(targetValue, sourceValue);
        else
          delete target[id];
      }
    }
  }

  return target;
}
© www.soinside.com 2019 - 2024. All rights reserved.