使用对象解构时省略 属性 变量

Omit property variable when using object destructuring

这是一个例子:

const initObject = {
  a: 0,
  b: 0,
  c: 0
}

const { a, ...rest } = initObject

我们从对象中省略了 属性 a,但是 const a 被分配了一个值,但从未使用过 - 来自 eslint 的错误(no-unused-vars)。是否可以完全省略const a

您可以创建一个 IIFE 并将对象传递给它。

const initObject = {
  a: 0,
  b: 0,
  c: 0
}
const res = (({a,...rest}) => (a,rest))(initObject);
console.log(res)

您可以使用 Object.assign() 创建对象的浅表副本,然后简单地删除 属性。

const initObject = {
  a: 0,
  b: 0,
  c: 0
}

let rest = Object.assign({}, initObject);
delete rest.a;

console.log(rest);
console.log(initObject);

尝试

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

一种可能的方法是使用 // eslint-disable-next-line no-unused-vars

例如

// eslint-disable-next-line no-unused-vars
const { a, ...rest } = initObject

或使用 ignoreRestSiblings

The ignoreRestSiblings option is a boolean (default: false). Using a Rest Property it is possible to “omit” properties from an object, but by default the sibling properties are marked as “unused”. With this option enabled the rest property’s siblings are ignored.

例如

/*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 documentation

The JavaScript delete operator removes a property from an object

例如

const initObject = {
  a: 0,
  b: 0,
  c: 0
}

const rest = { ...initObject }; // create a shallow copy
delete rest.a;

console.log(rest);

这似乎与 有细微的差别,但它避免了将声明中的所有变量标记为已使用的陷阱:

const initObject = {
  a: 0,
  b: 0,
  c: 0
}

const {
  a, // eslint-disable-line no-unused-vars
  ...rest
} = initObject

现在rest不用的话,还是会报eslint错误


关于问题

what's the correct way to remove a property then?

我要回答你应该问的问题。 处理具有您不需要的属性的对象的正确方法是以隐式忽略它们的方式重写您的逻辑。

  1. 如果您只需要属性 bc,则只解构这些属性:

    const { b, c } = initObject
    

    如果不需要,甚至不要承认 a 存在。

  2. 如果你的输入有很多你需要处理的特定属性,你不能假设initObject已经有精确它需要的布局,然后避免使用反射方法或Object.entries(), for...in, object spread and rest syntax等语法的诱惑

    继续单独处理您需要的特定属性,并在必要时将您的逻辑分解为可分离的函数,每个函数处理一个可管理的属性子集。

    另一方面,如果您 可以 预先调整您的输入以具有您已经需要的确切布局(例如,您可以假设 initObject 只有 bc),然后随意使用反射——这正是它的用途。

  3. 如果以上两点都不适用于你,你还是发现自己很想initObject有很多任意属性,还有一些您想忽略的,然后您应该使用此答案开头的建议(或其他适合您的答案之一)。

    但是,如前所述,这是 code-smell 并且表明您的逻辑需要对对象的布局更加宽松1,或者您的先决条件输入需要改变2.

error from eslint (no-unused-vars).

no-unused-vars rules 有两个配置选项可以帮助您的用例:

  • ignoreRestSiblings option 是一个布尔值,默认为 false。启用后,其余 属性 的兄弟姐妹将被忽略。这正是您所需要的!
  • varsIgnorePattern option specifies a regexp pattern for variable names not to be checked for usage. This allows us to make an exception for the 显式标记未使用的变量{ "varsIgnorePattern": "^_" }

    const { a:_, ...rest } = initObject;
    //       ^^
    

    不幸的是,您仍然需要避免多次声明 _ 变量,因此要省略多个属性,您需要执行类似 { a:_a, b:_b, ...rest } = ….

    [=42= 的操作]

Is it possible to completely omit const a?

完全避免引入任何标识符的糟糕技巧是使用

const { a:{}, ...rest } = initObject;
//       ^^^

进一步将 .a 属性 值解构为对象,但为此您需要确保 属性 存在并且不包含 nullundefined 值。

技术上 满足 linter 规则的选项是预先声明 rest,将 a 属性 解构为 rest,然后然后使用rest语法将对象的其余部分放入rest变量名:

const initObject = {
  a: 0,
  b: 0,
  c: 0
};
let rest;
({ a: rest, ...rest } = initObject);

console.log(rest);

不幸的是,如果你想避免var,你不能像

那样只用一行
let { a: rest, ...rest } = initObject

因为{的left-hand这边声明一个变量的时候,右边的每个新变量名都是单独初始化的——也就是,对口译员来说,它看起来有点像

let rest = initObject.a;
let rest = <everything else in initObject>

但不允许对同一变量名使用重复的 let 标识符。您 可以 var 在一行中完成,允许重复的标识符:

const initObject = {
  a: 0,
  b: 0,
  c: 0
};
var { a: rest, ...rest } = initObject;

console.log(rest);

但这有点奇怪。正如其他答案所建议的那样,我更喜欢 configure/ignore linter,或者使用解构以外的东西。

为了省略(清理)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,
        },                   
    }]);

我正在使用 PostgreSQL、Nest、Objection 和 Knex。