这里有一个例子:
const initObject = {
a: 0,
b: 0,
c: 0
}
const { a, ...rest } = initObject
我们从对象中省略了属性a
,但是然后给const a
赋值,但是它从未被使用 - eslint的错误(no-unused-vars)。是否可能完全省略const a
?
这里有一个例子:
const initObject = {
a: 0,
b: 0,
c: 0
}
const { a, ...rest } = initObject
我们从对象中省略了属性a
,但是然后给const a
赋值,但是它从未被使用 - eslint的错误(no-unused-vars)。是否可能完全省略const a
?
一种可能的方法是使用// eslint-disable-next-line no-unused-vars
例如:
// eslint-disable-next-line no-unused-vars
const { a, ...rest } = initObject
或者通过使用ignoreRestSiblings
来实现。
ignoreRestSiblings选项是一个布尔值(默认为false)。使用Rest属性可以从对象中“省略”属性,但默认情况下兄弟属性被标记为“未使用”。启用此选项后,忽略了rest属性的兄弟属性。
例如:
/*eslint no-unused-vars: ["error", { "ignoreRestSiblings": true }]*/
// 'a' is ignored because it has a rest property sibling.
const { a, ...rest } = initObject;
了解有关no-unused-vars
的更多信息。
但是,如果您的目标是删除属性a
,则还有另一种方法。
您可以使用delete
运算符。
来自MDN文档
JavaScript的
delete
运算符从对象中移除一个属性
例如:
const initObject = {
a: 0,
b: 0,
c: 0
}
const rest = { ...initObject }; // create a shallow copy
delete rest.a;
console.log(rest);
eslint出现错误 (no-unused-vars)
no-unused-vars规则有两个配置选项可帮助您解决此问题:
ignoreRestSiblings
选项是一个布尔值,默认为false
。启用时,将忽略rest属性的兄弟姐妹。这正是您需要的!varsIgnorePattern
选项指定变量名称的正则表达式模式,以不检查使用情况的变量名。这使我们可以针对常见的下划线标识符进行例外处理,以通过{ "varsIgnorePattern": "^_" }
明确标记未使用的变量。
const { a:_, ...rest } = initObject;
// ^^
不幸的是,您仍需要避免多次声明_
变量,因此要省略多个属性,您需要执行类似于{ a:_a, b:_b, ...rest } = …
的操作。
是否可以完全省略
const a
?
一种完全避免引入任何标识符的不好办法是使用
const { a:{}, ...rest } = initObject;
// ^^^
进一步将.a
属性值解构为一个对象,但这需要确保该属性存在且不持有null
或undefined
值。
const { a: {} = {}, ...rest } = initObject
可以允许 a
为 undefined
,但看起来更糟糕。 - Patrick Roberts这似乎是与@R3tep的答案微不足道的偏差,但这避免了将声明中的所有变量都标记为已使用的陷阱:
const initObject = {
a: 0,
b: 0,
c: 0
}
const {
a, // eslint-disable-line no-unused-vars
...rest
} = initObject
现在,如果未使用rest
,它仍会导致eslint错误。
关于问题:
删除属性的正确方法是什么?
我将回答您应该提出的问题。处理具有不需要的属性的对象的正确方法是以一种隐式地忽略它们的方式重写您的逻辑。
If you just need the properties b
and c
, destructure only those properties:
const { b, c } = initObject
Don't even acknowledge that a
exists if you don't need it.
If your input has a lot of specific properties you need to deal with, and you can't assume that initObject
already has the exact layout it needs, then avoid the temptation to use reflection methods or syntax like Object.entries()
, for...in
, object spread and rest syntax, etc.
Continue to handle the specific properties you need on an individual basis, and break up your logic into separable functions that each deal with a manageable subset of the properties, if necessary.
On the other hand, if you can precondition your input to have the exact layout you already need (e.g. you are able to assume that initObject
only has b
and c
), then feel free to use reflection -- that's exactly what it's for.
If neither of the above two points applies to you and you still find that you really want initObject
to have a lot of arbitrary properties, and a few that you want to ignore, then you should use the suggestion at the beginning of this answer (or one of the other answers that works for you).
However, as noted, this is code-smell and an indicator that your logic needs to be more lenient with the layout of the object1, or your preconditions for the input need to change2.
...rest
部分,它会迭代 initObject
的剩余属性并将它们复制到 rest
中,这也是为什么它被认为是代码异味的一部分。 - Patrick Robertsconst initObject = {
a: 0,
b: 0,
c: 0
}
const res = (({a,...rest}) => (a,rest))(initObject);
console.log(res)
const initObject = {
a: 0,
b: 0,
c: 0
};
let rest;
({ a: rest, ...rest } = initObject);
console.log(rest);
var
,你不能像这样在单行中完成。"最初的回答"let { a: rest, ...rest } = initObject
{
的左侧声明一个变量时,右侧每个新的变量名称都会被单独初始化 - 对解释器来说,它看起来有点像"最初的回答"。let rest = initObject.a;
let rest = <everything else in initObject>
但是,对于同一变量名的重复let
标识符是不允许的。您可以使用var
在一行中完成它,因为var
允许重复标识符:
最初的回答
const initObject = {
a: 0,
b: 0,
c: 0
};
var { a: rest, ...rest } = initObject;
console.log(rest);
但这有点奇怪。我更喜欢配置/忽略linter,或者像其他回答建议的那样使用其他技术。
最初的回答
const rest = ((o)=> (delete o.a,o))({...initObject});
'use strict'
const initObject = {
a: 0,
b: 0,
c: 0
}
const rest = ((o)=> (delete o.a,o))({...initObject});
console.log({initObject,rest});
a
没有使用。 - Patrick RobertsObject.assign()
创建一个浅拷贝对象,然后简单地删除属性。
const initObject = {
a: 0,
b: 0,
c: 0
}
let rest = Object.assign({}, initObject);
delete rest.a;
console.log(rest);
console.log(initObject);
为了省略(清理)ID和密码属性,以下是最终在单个对象中运行的代码。
这是产品和用户模型之间关系的响应。
return {...product,
author: [
`username: ` + product['author'].username,
`email: ` + product['author'].email,
]};
return products.map(product => [{
'title' : product['title'],
'description' : product['description'],
'price' : product['price'],
'updated' : product['updatedAt'],
'author': {
'username' : product['author'].username,
'email' : product['author'].email,
},
}]);
const rest = initObject
改成了const rest = { ...initObject }
? - Alexander KiminitObject
而不是创建浅拷贝,delete rest.a
也会修改initObject
。 - Patrick Roberts