J'utilise le paramètre rest pour effectuer certaines opérations, mais certaines propriétés ont disparu dans le résultat.
Le format de données de this.props
ressemble à ceci:
``` class Parent { constructor() { this.props = { data: '123', }; } } class Child extends Parent { constructor() { super(); this.props.childProp = 'test'; let {test, ...otherProps} = this.props; console.log('data' in this.props, 'data' in otherProps); // true true } } new Child(); ```
Et j'ai essayé de le mettre au repos de cette manière:
``` let {showWaveAnimation, ...otherProps} = this.props; console.log('data' in otherProps); // false console.log('data' in this.props); //true ```
Pourquoi la propriété 'data' aurait-elle été perdue après avoir essayé l'opération de repos?
Selon MDN , J'ai trouvé la description:
les paramètres de repos sont uniquement ceux qui n'ont pas reçu de nom séparé (c'est-à-dire formellement défini dans l'expression de fonction), tandis que l'objet arguments contient tous les arguments passés à la fonction;
Que signifie ici nom séparé
? Est-ce que cela signifie que les propriétés qui s'étendent de son prototype ne seraient pas du repos? Mais après avoir essayé les déclarations suivantes, j'ai obtenu le même résultat, je suis confus.
``` this.props = { data: [{...}, ...], ... } ```
L'ancien comportement du code anormal après la transpilation de Babel, pourrait-il être le problème du plugin de Babel?
AJOUTER: J'ai trouvé que ce concept peut être plus précis dans la description de mes opérations repos
. https://developer.mozilla.org/ fr-FR / docs / Web / JavaScript / Reference / Operators / Destructuring_assignment # Rest_in_Object_Destructuring
3 Réponses :
Le paramètre rest vous permet d'obtenir tous les attributs restants non déjà sélectionnés par l'identifiant qui le précède dans l'affectation.
const obj = { a: 1, b: 2, c: 3 } const { d, ...rest } = obj; console.log(d); console.log(rest);
Au-dessus de obj
a une propriété nommée a
donc elle est déstructurée de obj
et assignée à la variable a
, alors toutes les autres propriétés sont affectées dans un objet à rest
.
const obj = { a: 1, b: 2, c: 3 } const { a, ...rest } = obj; console.log(a); console.log(rest);
Ici, obj
n'a pas de propriété nommée d
. Il est donc déstructuré de obj
en tant que undefined
et associé à la variable a
. Ensuite, toutes les autres propriétés non encore attribuées, c'est-à-dire a
, b
et c
sont données à rest
.
Dans votre code, otherProps
a les mêmes propriétés que this.props
, car l'objet this.props
n'a pas une propriété nommée test
. En d'autres termes, pour déstructurer un objet, vous devez connaître sa structure.
Cela ne répond pas à ceci: console.log ('data' dans otherProps); // faux
@Rajesh C'est en fait le paramètre d'énumérables, j'ajoute un exemple dans la réponse.
les paramètres de repos sont uniquement ceux qui n'ont pas reçu de nom séparé (c'est-à-dire formellement défini dans l'expression de fonction), tandis que l'objet arguments contient tous les arguments passés à la fonction;
Que signifie ici un nom séparé? Est-ce que cela signifie que les propriétés qui s'étendent de son prototype ne seraient pas du repos? Mais après avoir essayé les déclarations suivantes, j'ai obtenu le même résultat, je suis déroutant.
Étant donné une définition de fonction
function foo (a, b, ... c) {}
, les argumentsa
etb
sont les les paramètres nommés, tandis que le reste des arguments passés est réparti dans la dernière variablec
. Maintenant,c
est une variable nommée, mais tous les paramètres passés à partir de la troisième ne seront accessibles que dansc
, c'est-à-direc [ 0]
.Maintenant, votre erreur console.log provient de votre utilisation du
Vous utilisez en fait l'opérateur spread pour déstructurer votre objet props en plusieurs variables nommées.in
opérateur. Vous avez défini un objetconst foo = {'data': 'bar'}
.'data' dans foo
est vrai, mais'blarg' dans foo
est faux car foo ne contient pas de clé / propriété nommée 'blarg'.
const bar = (a, b, ...c) => { console.log(`a: ${a}`); console.log(`b: ${b}`); console.log(`c: ${c}`); }; bar('this is first param', 42, 'foo', 'bar', '1', 2, 'stackoverflow');
// This is an example of the rest operator const foo = (...allTheArgs) => { allTheArgs.forEach(e => console.log(e)); } foo(1,2,3); // all the args are collected into a single array variable in the function
const object = { data: 'foo', other: 'bar', moreData: [1,2,3], }; // Example usage of the spread operator const { data, ...allTheRest} = object; // data is destructured, other and moreData into allTheRest console.log(data); console.log(allTheRest); // in operator console.log('data' in object); // true console.log('data' in allTheRest); // false console.log('moreData' in allTheRest); // true
En fait, j'ai trouvé que c'est parce que la propriété 'data' de mon objet n'est pas énumérable, mais merci d'avoir répondu! Ce qui me trouble, c'est que puis-je appeler a
et b
dans votre code un nom distinct ?
J'ai ajouté un troisième exemple pour montrer comment utiliser a
et b
. J'espère que cela répond à votre question.
J'ai compris pourquoi 'data' a disparu dans mon résultat de repos, c'est la propriété énumérable
du champ 'data'!
Une fois, la propriété est définie comme enumerable: false , nous ne pouvons pas l'obtenir avec l'opération de repos dans la déstructuration d'objets.
Selon MDN
La proposition Rest / Spread Properties pour ECMAScript (étape 3) ajoute la syntaxe rest à la déstructuration. Les propriétés de repos collectent les clés de propriété énumérables restantes qui ne sont pas déjà sélectionnées par le modèle de déstructuration.
Je pense que cet exemple peut expliquer mes idées plus précisément:
const person = { name: 'Dave', surname: 'Bowman' }; Object.defineProperty(person, 'age', { enumerable: false, // Make the property non-enumerable value: 25 }); console.log(person['age']); // => 25 const clone = { ...person }; console.log(clone); // => { name: 'Dave', surname: 'Bowman' }
Modifiez-vous / définissez-vous enumerable: false
pour les données? Ce n'est pas visible en question
@Rajesh En fait, c'est false
exactement, mais c'est défini par le framework, donc je ne l'ai pas remarqué au début.
@Rajesh Salut, je l'utilise dans
Object
, il n'est donc pas nécessaire de le garder indexé en tant que tableau? Et l'opération que j'ai écrite dans la classeChild
peut fonctionner normalement.Ne pas être pédant ici, mais il semble que vous vous posiez des questions sur opérateur de diffusion . Il utilise la même syntaxe, mais présente une différence d'utilisation subtile, mais essentielle.
@DrewReese Je pense que je recherche la bonne méthode pour me reposer dans la déstructuration d'objets?