【问题标题】:Delete an object property with Object.assign()使用 Object.assign() 删除对象属性
【发布时间】:2018-07-17 05:39:23
【问题描述】:

是否可以删除带有Object.assign() 的键,而不是在以下示例中将值设置为undefined

我正在使用.filter() 浏览一些项目。当有匹配时,我想添加/更改 x 属性值并删除 y 和 z 属性(而不是将它们设置为未定义)。

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

【问题讨论】:

  • this.state.items.filter(item => item.id === file.id ? { x: 'x'} : item) 怎么样?
  • 不,用 Object.assign() 删除一个键是不可能的,你可以覆盖它。要删除它,你必须明确地这样做
  • 仅供参考,Object.assign 的第一个参数是目标。所以它会变异 item 这是一种不好的做法
  • 你为什么使用filter()而不是map()你的过滤器中的函数没有返回一个令人困惑的布尔值。
  • 只需添加您尝试智能关闭的三行代码。你的代码会更清晰,几个月后你会很开心。

标签: javascript node.js reactjs object


【解决方案1】:

不是的,看看官方的 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)
        });
    })
    

    【讨论】:

      【解决方案3】:

      虽然它不允许您通过 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)

      【讨论】:

      • 我认为我们的目标是实际上也改变原始项目。不只是一个副本。 (但我很可能错了)
      猜你喜欢
      • 2017-03-12
      • 1970-01-01
      • 1970-01-01
      • 2021-01-16
      • 2014-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多