使用Object.assign()删除对象属性

4
在以下示例中,使用 Object.assign() 删除键而不是将值设置为 undefined 是否可行?
我正在使用 .filter() 浏览一些项。当有匹配时,我想添加/更改x属性值并删除y和z属性(而不是将它们设置为undefined)。
files.forEach(file => {
    this.setState({ 
        items: this.state.items.filter(item => item.id === file.id ? Object.assign(item, { x: 'x', y: undefined, z: undefined }) : item) 
    });
})

2
这个怎么样:this.state.items.filter(item => item.id === file.id ? { x: 'x'} : item) - Oluwafemi Sule
不,使用Object.assign()无法删除键,你只能覆盖它。要删除它,必须明确执行删除操作。 - simbathesailor
1
只是提供信息,Object.assign 的第一个参数是目标对象。所以它会改变 item,这是一种不好的做法。 - Rajesh
1
为什么你在使用 filter() 而不是 map()?你在 filter 函数内部的函数没有返回布尔值,这很令人困惑。 - Mark
只需添加你试图“智能化”的三行代码。你的代码将更清晰,当你几个月后回来时,你会感到高兴。 - Kaiido
如果您喜欢我的努力,请批准我的答案。 - Ratan Uday Kumar
3个回答

2

这并不是问题,可以查看官方的polyfill做法,来自MDN

if (typeof Object.assign != 'function') {
  // Must be writable: true, enumerable: false, configurable: true
  Object.defineProperty(Object, "assign", {
    value: function assign(target, varArgs) { // .length of function is 2
      'use strict';
      if (target == null) { // TypeError if undefined or null
        throw new TypeError('Cannot convert undefined or null to object');
      }

      var to = Object(target);

      for (var index = 1; index < arguments.length; index++) {
        var nextSource = arguments[index];

        if (nextSource != null) { // Skip over if undefined or null
          for (var nextKey in nextSource) {
            // Avoid bugs when hasOwnProperty is shadowed
            if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
              to[nextKey] = nextSource[nextKey];
            }
          }
        }
      }
      return to;
    },
    writable: true,
    configurable: true
  });
}

没有可以删除键的易受攻击功能。


您需要使用显式的delete,例如:

const updateMatch = (item, file, add, unset) => {

    if(item.id !== file.id)
        return item;

    unset.forEach(key => {

        delete item[key];

    });

    return Object.assign(item, add);

} 

files.forEach(file => {
    this.setState({ 
        items: this.state.items.filter(item => updateMatch(item, file, { x: 'x' }, ['y', 'z'])) 
    });
})

2

尝试以下方法:

var jbt = {
    "name": "uday",
    "age": "25"
}
console.log("Before Change--->", jbt);
jbt = Object.assign({}, delete jbt.age, jbt);
console.log("Afetr Change--->", jbt);

控制台结果

Before Change---> { name: 'uday', age: '25' }
Afetr Change---> { name: 'uday' }

针对您的情况,可以尝试以下方法:

files.forEach(file => {
    this.setState({
        items: this.state.items.filter(item => item.id === file.id ? Object.assign({}, delete item.y, delete item.z, item) : item)
    });
})

0

虽然它不允许您通过Object.assign删除,但您可以使用ES6解构来以清晰明了的方式帮助解决这个问题:

let file = {id: 12}
let items = [
    {id: 1, x: 1, y:2, z: 13},
    {id: 12, x: 3, y:6, z: 23},
    {id: 13, x: 2, y:9, z: 33},
    {id: 14, x: 4, y:12, z: 43}
]
items = items.map(item => {
    let {y, z, ...obj} = item
    return item.id === file.id ? Object.assign(obj, { x: 'x'}) : item
}) 
console.log(items)


1
我认为目标实际上是要改变原始项目,而不仅仅是复制它们。(但我很可能非常错误) - Kaiido

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接