Какие свойства будут пропущены при деструктуризации объектов?

Я использую параметр rest для выполнения некоторых операций, но в результате некоторые свойства исчезли.

Формат данных this.props выглядит так:

```
this.props = {
  data: [{...}, ...],
  ...
}
```

И я попытался успокоить его так:

```
let {showWaveAnimation, ...otherProps} = this.props;

console.info('data' in otherProps); // false
console.info('data' in this.props); //true
```

Почему свойство data потеряно после того, как я попробовал операцию отдыха?

По MDN нашел описание:

rest parameters are only the ones that haven't been given a separate name (i.e. formally defined in function expression), while the arguments object contains all arguments passed to the function;

Что здесь означает separate name? Означает ли это, что свойства, которые простираются от его прототипа, не останутся без покоя? Но после того, как я попробовал следующие утверждения, я получил тот же результат, я сбиваю с толку.

```
class Parent {
    constructor() {
        this.props = {
            data: '123',
        };
    }
}

class Child extends Parent {
    constructor() {
        super();
        this.props.childProp = 'test';

        let {test, ...otherProps} = this.props;
        console.info('data' in this.props, 'data' in otherProps);
        // true true
    }
}

new Child();
```

Неправильное поведение прежнего кода после транспиляции Babel, может быть проблема с плагином Babel?

ДОБАВИТЬ: Я обнаружил, что эта концепция может быть более точной при описании моих операций с rest. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Rest_in_Object_Destructuring

@Rajesh Привет, я использую его в Object, поэтому нет необходимости хранить его в индексе как массив? И операция, которую я написал в классе Child, может нормально работать.

hijiangtao 11.01.2019 07:03

Не хочу быть педантичным, но, похоже, вы действительно спрашиваете о оператор распространения. Он использует тот же синтаксис, но имеет тонкую, но ключевую разницу в использовании.

Drew Reese 11.01.2019 07:32

@DrewReese Я думаю, что действительно ищу правильный метод отдыха при деструктуризации объекта?

hijiangtao 11.01.2019 07:45
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
417
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Параметр rest позволяет получить все остальные атрибуты, еще не выбранные по идентификатору, предшествующему ему в назначении.

  • Возьмем простой пример:

const obj = {
  a: 1,
  b: 2,
  c: 3
}

const { a, ...rest } = obj;

console.info(a);
console.info(rest);

Вышеупомянутый obj имеет свойство с именем a, поэтому он деструктурируется из obj и назначается переменной a, затем все остальные свойства назначаются в объекте для rest.

  • Однако то, что у вас есть, больше похоже:

const obj = {
  a: 1,
  b: 2,
  c: 3
}

const { d, ...rest } = obj;

console.info(d);
console.info(rest);

Здесь obj не имеет свойства с именем d. Таким образом, он деструктурируется из obj как undefined и присваивается переменной a. Затем a передаются все другие свойства, которые еще не присвоены, то есть b, c и rest.

В вашем коде otherProps имеет те же свойства, что и this.props, потому что объект this.props не имеет свойства с именем test. Другими словами, чтобы разрушить объект, вы должны знать его структуру.

Это не ответ на этот вопрос: console.info('data' in otherProps); // false

Rajesh 11.01.2019 07:27

@Rajesh На самом деле это настройка enumerable, я добавляю пример в ответ.

hijiangtao 11.01.2019 08:16

rest parameters are only the ones that haven't been given a separate name (i.e. formally defined in function expression), while the arguments object contains all arguments passed to the function;

What does separate name here means? Is it means properties that extends from its prototype would not be rest? But after I tried the following statements, I got the same result, I am confusing.

Учитывая определение функции function foo(a, b, ...c) {}, аргументы a и b являются именованными параметрами, тогда как остальные переданные аргументы распространяются на последнюю переменную c. Теперь cявляется - именованная переменная, но любые параметры, переданные с третьей, будут доступны только в c, то есть c[0].

Теперь ваша ошибка console.info возникает из-за использования вами оператора in. Вы определили объект const foo = {'data': 'bar'}. 'data' in foo - истина, но 'blarg' in foo - ложь, поскольку foo не содержит ключа / свойства с именем 'blarg'.

Фактически вы используете оператор распространения, чтобы разложить свой объект props на несколько именованных переменных.

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.info(data);
console.info(allTheRest);

// in operator
console.info('data' in object); // true
console.info('data' in allTheRest); // false
console.info('moreData' in allTheRest); // true

// This is an example of the rest operator
const foo = (...allTheArgs) => {
  allTheArgs.forEach(e => console.info(e));
}

foo(1,2,3); // all the args are collected into a single array variable in the function

const bar = (a, b, ...c) => {
  console.info(`a: ${a}`);
  console.info(`b: ${b}`);
  console.info(`c: ${c}`);
};

bar('this is first param', 42, 'foo', 'bar', '1', 2, 'stackoverflow');

На самом деле я обнаружил, что свойство data в моем объекте не перечислимо, но спасибо за ответ! Что меня смущает, так это то, могу ли я назвать a, а b в вашем коде получил отдельное имя?

hijiangtao 11.01.2019 07:49

Я добавил третий пример, чтобы показать, как использовать a и b. Надеюсь, это ответит на ваш вопрос.

Drew Reese 11.01.2019 08:03
Ответ принят как подходящий

Я понял, почему в моем результате отдыха исчезли «данные», это свойство enumerable поля «данные»!

После того, как свойство установлено как enumerable: false, мы не можем получить его с помощью операции rest при деструктуризации объекта.

По данным MDN

The Rest/Spread Properties for ECMAScript proposal (stage 3) adds the rest syntax to destructuring. Rest properties collect the remaining own enumerable property keys that are not already picked off by the destructuring pattern.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Rest_in_Object_Destructuring

Думаю, этот пример может более точно объяснить мои идеи:

const person = {  
  name: 'Dave',
  surname: 'Bowman'
};

Object.defineProperty(person, 'age', {  
  enumerable: false, // Make the property non-enumerable
  value: 25
});
console.info(person['age']); // => 25

const clone = {  
  ...person
};
console.info(clone); // => { name: 'Dave', surname: 'Bowman' }

Вы меняете / настраиваете enumerable: false для данных? Его не видно под вопросом

Rajesh 11.01.2019 08:35

@Rajesh На самом деле, это именно false, но он определяется фреймворком, поэтому я не заметил этого вначале.

hijiangtao 12.01.2019 16:08

Другие вопросы по теме