Какие свойства будут пропущены при уничтожении объектов? - PullRequest
0 голосов
/ 11 января 2019

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

Формат данных this.props выглядит следующим образом:

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

И я попытался сделать так:

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

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

Почему свойство 'data' потеряно после попытки перезапуска?

Согласно MDN , я нашел описание:

остальные параметры - это только те, которым не было дано отдельное имя (то есть формально определенное в выражении функции), в то время как объект arguments содержит все аргументы, переданные функции;

Что означает 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.log('data' in this.props, 'data' in otherProps);
        // true true
    }
}

new Child();
```

Прежнее поведение кода, ненормальное после перехода Бабеля, может ли это быть проблемой с плагином Бабеля?

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

Ответы [ 3 ]

0 голосов
/ 11 января 2019

параметры rest - это только те, которым не было дано отдельное имя (то есть формально определенное в выражении функции), в то время как объект arguments содержит все аргументы, переданные функции;

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

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

Теперь ваша ошибка console.log связана с использованием вами оператора 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.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

// 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 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');
0 голосов
/ 11 января 2019

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

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

Согласно MDN

Свойства Rest / Spread для предложения ECMAScript (этап 3) добавляют синтаксис остатка к деструктуризации. Остальные свойства собирают оставшиеся собственные ключи перечислимых свойств, которые еще не обнаружены шаблоном деструктурирования.

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.log(person['age']); // => 25

const clone = {  
  ...person
};
console.log(clone); // => { name: 'Dave', surname: 'Bowman' }
0 голосов
/ 11 января 2019

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

  • Давайте рассмотрим простой пример:

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

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

console.log(a);
console.log(rest);

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

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

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

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

console.log(d);
console.log(rest);

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

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

...