JavaScript - 使用展开和剩余语法从对象中删除特定属性

21

我有一个如下所示的对象:

let obj = {foo: 1, bar: 2, baz: 3}

我想通过调用一个接受属性名作为参数的方法来删除特定的属性。

removeProperty(obj, propertyName) {
  let { propertyName, _, ...result } = obj
  return result
}
问题在于这种方法仅在语法扩展中直接写入属性名称时才起作用,例如:let { bar, _, ...result } = obj。但是将其作为参数传递时不起作用,因为语法扩展会将其创建为一个新变量。
如果可能的话,请给出另一种解决方案,除了使用lodash的omit方法。
3个回答

41

在解构中可以使用计算属性:

let obj = {foo: 1, bar: 2, baz: 3}
function removeProperty(obj, propertyName) {
  let { [propertyName]: _, ...result } = obj
  return result
}
console.log(removeProperty(obj, 'foo'));

这将把名称为 propertyName 的属性分配给一个临时变量,并基本上删除该键。请参见MDN文档


为什么将其设置为下划线会删除它? - Wills Manley
@manley13 不需要这样。下划线可以是任何东西。在编程中使用下划线作为虚拟变量只是一种惯例,因为它没有被使用。 - Andrew Li
如果propertyName是一个数组,这是否可行?试图一次从对象中删除多个计算属性。 - Marc Sloth Eastman
@MarcSlothEastman 我不知道有没有其他方法。你可以像其他答案中那样使用循环和 delete,或者过滤掉键:Object.keys(obj).filter(key => !forbiddenKeys.includes(key)).reduce((acc, key) => ({ ...acc, [key]: obj[key] }), {}),但这看起来非常难看。最好还是采用前一种方法更清晰明了。 - Andrew Li

10

除了使用 destructuring 以外,另一种选择是使用 delete。以下方案将时间复杂性相比于 destructuring 减少约 35% (在桌面版 Chrome 中)。

解决方案

let obj = {foo: 1, bar: 2, baz: 3}
function removeProperty(obj, propertyName) {
  let newObj = {...obj};
  delete newObj[propertyName];
  return newObj;
}
console.log(removeProperty(obj, 'foo'));

性能测试

https://jsperf.com/so53753276

结果因所用浏览器而异。结果相当引人入胜。桌面版Safari的解构优于删除,但桌面版Chrome比桌面版Safari所有数字都表现更好。

+-----------------------------------+
| Browser | delete    | destructure |
+---------+-----------+-------------+
| Chrome  | 3,229,791 | 1,993,256   |
| Safari  | 1,186,679 | 1,872,396   | 
+---------+-----------+-------------+

iOS上的结果并不令人意外,因为Chrome实际上就是在Safari引擎下运行。

+-----------------------------------+
| Browser | delete    | destructure |
+---------+-----------+-------------+
| Chrome  | 1,146,496 | 1,785,551   |
| Safari  | 1,182,067 | 1,793,772   | 
+---------+-----------+-------------+

Documentation

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete


有趣的是,在Safari iOS上,我的代码运行得更快。克隆然后删除的速度慢了43%。 - Andrew Li
@Li357,从整体上看,您的解决方案似乎确实是最高效的,但是在涉及“delete”时,桌面版Chrome的表现确实超出了所有其他浏览器的想象。 - AnonymousSB

4
values = {
    id: 1,
    name: 'hello world',
    vehicle: 'car',
    time: '3.30 pm',
    date: '02 MAR 1990',
};

const { time, date, ...rest } = values;

now ***...rest*** contains the object values of {
    id: 1,
    name: 'hello world',
    vehicle: 'car',
};

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