使用对象分解时忽略属性变量

时间:2019-05-15 14:23:33

标签: javascript ecmascript-6 eslint object-destructuring

这里是一个例子:

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

const { a, ...rest } = initObject

我们从对象中省略了属性a,但是随后const a被分配了一个值,但从未使用过-eslint错误(无未使用的变量)。是否可以完全省略const a

8 个答案:

答案 0 :(得分:13)

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

例如

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

或使用ignoreRestSiblings

  

ignoreRestSiblings选项是一个布尔值(默认值:false)。使用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 documentation

  

JavaScript delete 运算符从对象中删除属性

例如

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

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

console.log(rest);

答案 1 :(得分:7)

这似乎与@R3tep's answer有微不足道的区别,但它避免了将声明中的所有变量标记为已使用的陷阱:

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

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

现在,如果rest未使用,它仍然会导致eslint错误。


关于这个问题

  

那么删除属性的正确方法是什么?

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

  1. 如果只需要属性bc,则仅对那些属性进行解构:

    const { b, c } = initObject
    

    甚至不需要承认a的存在。

  2. 如果您的输入具有很多需要处理的特定属性,并且您不能假设initObject已经具有 exact 所需的布局,然后避免尝试使用反射方法或诸如Object.entries()for...inobject spread and rest syntax等语法的诱惑。

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

    另一方面,如果您可以进行前提条件输入,使其具有您已经需要的确切布局(例如,您可以假设initObject仅具有bc),然后随时使用反射-就是这样。

  3. 如果以上两点都不适合您,您仍然发现自己确实希望initObject具有很多任意属性,并且还需要一些忽略,然后,您应该在此答案的开头(或对您有用的其他答案之一)中使用建议。

    但是,如前所述,这是代码气味,它指示您的逻辑需要对对象 1 的布局更加宽大,或者输入的前提条件需要更改 2

答案 2 :(得分:4)

  

eslint的错误(未使用的变量)。

no-unused-vars rules有两个配置选项,可帮助您解决用例:

  • ignoreRestSiblings option是一个布尔值,默认为false。启用后,其余属性的同级将被忽略。这正是您所需要的完全
  • varsIgnorePattern option为不检查其用法的变量名指定了正则表达式模式。这使我们可以对common underscore identifier进行例外处理,以用{ "varsIgnorePattern": "^_" }显式标记未使用的变量。

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

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

  

是否可以完全省略const a

一个完全避免引入任何标识符的不良技巧将被使用

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

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

>

答案 3 :(得分:2)

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

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

答案 4 :(得分:2)

在技术上满足linter规则的一个选项是预先声明rest,将a属性解构为rest,然后然后< / em>使用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

因为{的左侧声明了一个变量,所以右侧的每个新变量名都分别进行了初始化的操作-也就是说,对于解释器来说,它看起来有点喜欢

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

但这有点奇怪。正如其他答案所建议的那样,我宁愿配置/忽略lint,还是使用除销毁之外的其他方法。

答案 5 :(得分:1)

您可以使用Object.assign()创建对象的浅表副本,只需删除属性即可。

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

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

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

答案 6 :(得分:1)

尝试

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

答案 7 :(得分:0)

为了省略(清理)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。