web-dev-qa-db-fra.com

Omettre la variable de propriété lors de l'utilisation de la déstructuration d'objets

Voici un exemple:

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

const { a, ...rest } = initObject

Nous omettons la propriété a de l'objet, mais alors const a est assigné une valeur, mais jamais utilisé - erreur de eslint (no-non utilisé-vars). Est-il possible d'omettre complètement const a?

22
Alexander Kim

Une façon possible consiste à utiliser // eslint-disable-next-line no-unused-vars

par exemple.

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

Ou en utilisant ignoreRestSiblings

L'option ignoreRestSiblings est un booléen (par défaut: false). En utilisant une propriété Rest, il est possible "d'omettre" les propriétés d'un objet, mais par défaut, les propriétés frère sont marquées comme "inutilisées". Lorsque cette option est activée, les frères et sœurs de la propriété rest sont ignorés.

par exemple.

/*eslint no-unused-vars: ["error", { "ignoreRestSiblings": true }]*/
// 'a' is ignored because it has a rest property sibling.
const { a, ...rest } = initObject;

Plus d'informations sur no-unused-vars


Mais si votre objectif est de supprimer la propriété a, il existe un autre moyen.
Vous pouvez utiliser l'opérateur delete .

De documentation MDN

L'opérateur JavaScript delete supprime une propriété d'un objet

par exemple.

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

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

console.log(rest);
15
R3tep

Cela peut sembler un écart trivial par rapport à @ réponse de R3tep , mais cela évite l'écueil de marquer toutes les variables de la déclaration comme utilisées:

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

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

Maintenant, si rest n'est pas utilisé, cela provoquera toujours une erreur eslint.


Concernant la question

quelle est la bonne façon de supprimer une propriété alors?

Je vais plutôt répondre à la question que vous auriez dû poser. La bonne façon de gérer un objet avec des propriétés dont vous n'avez pas besoin est de réécrire votre logique d'une manière qui implicitement les ignore.

  1. Si vous avez juste besoin des propriétés b et c, ne détruisez que ces propriétés:

    const { b, c } = initObject
    

    Ne reconnaissez même pas que a existe si vous n'en avez pas besoin.

  2. Si votre entrée a beaucoup de propriétés spécifiques que vous devez traiter et que vous ne pouvez pas supposer que initObject possède déjà le = exact la mise en page dont il a besoin, puis éviter la tentation d'utiliser des méthodes de réflexion ou une syntaxe comme Object.entries() , - for...in , syntaxe de répartition et de repos des objets , etc.

    Continuez à gérer les propriétés spécifiques dont vous avez besoin sur une base individuelle, et décomposez votre logique en fonctions séparables qui traitent chacune d'un sous-ensemble gérable des propriétés, si nécessaire.

    D'un autre côté, si vous pouvez préconditionnez votre entrée pour avoir la disposition exacte dont vous avez déjà besoin (par exemple, vous pouvez supposer que initObject n'a que b et c), alors n'hésitez pas à utiliser la réflexion - c'est exactement à cela que ça sert.

  3. Si aucun des deux points ci-dessus ne s'applique à vous et que vous trouvez toujours que vous voulez vraiment que initObject ait beaucoup de propriétés arbitraires , et quelques-unes que vous voulez ignorer, alors vous devez utiliser la suggestion au début de cette réponse (ou l'une des autres réponses qui vous convient).

    Cependant, comme indiqué, c'est une odeur de code et un indicateur que votre logique doit être plus indulgente avec la disposition de l'objet1, ou vos conditions préalables pour l'entrée doivent changer2.

8
Patrick Roberts

erreur d'eslint (pas de vars non utilisés).

Les règles de non-utilisation de vars ont deux options de configuration qui vous aideront dans votre cas d'utilisation:

  • L'option ignoreRestSiblings est un booléen qui prend par défaut false. Lorsqu'elle est activée, les frères et sœurs de la propriété rest sont ignorés. C'est exactement ce dont vous avez besoin!
  • L'option varsIgnorePattern spécifie un modèle d'expression régulière pour les noms de variables dont l'utilisation ne doit pas être vérifiée. Cela nous permet de faire une exception pour le communidentificateur de soulignement pour marquer explicitement les variables inutilisées avec { "varsIgnorePattern": "^_" }.

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

    Malheureusement, vous devez toujours éviter les déclarations multiples de _ variable, donc pour omettre plusieurs propriétés, vous devez faire quelque chose comme { a:_a, b:_b, ...rest } = ….

Est-il possible d'omettre complètement const a?

Un mauvais hack qui évite complètement d'introduire un identifiant serait d'utiliser

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

qui déstructure davantage le .a valeur de propriété dans un objet, mais pour cela, vous devez vous assurer que la propriété existe et ne contient pas de valeur null ou undefined.

5
Bergi

Vous pouvez créer un IIFE et lui passer un objet.

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

Une option qui techniquement remplit les règles de linter consiste à déclarer rest dès le départ, à détruire la propriété a en rest, et alors utilisez la syntaxe rest pour placer le reste de l'objet dans le nom de variable rest:

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

console.log(rest);

Malheureusement, si vous voulez éviter var, vous ne pouvez pas le faire en une seule ligne comme

let { a: rest, ...rest } = initObject

car lorsque le côté gauche du { déclare une variable, chaque nouveau nom de variable sur le côté droit est initialisé séparément - c'est-à-dire que pour l'interprète, il ressemble un peu à

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

Mais les identificateurs let en double pour le même nom de variable ne sont pas autorisés. Vous pourriez le faire en une seule ligne avec var, pour lequel des identificateurs en double sont autorisés:

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

console.log(rest);

Mais tout cela est un peu étrange. Je préfère configurer/ignorer le linter, ou utiliser autre chose que la déstructuration, comme d'autres réponses l'ont suggéré.

2

essayer

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

Vous pouvez créer une copie superficielle de l'objet à l'aide de Object.assign() et simplement supprimer la propriété.

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

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

console.log(rest);
console.log(initObject);
1
amrender singh