Опустить переменную свойства при использовании деструктуризации объекта - PullRequest
20 голосов
/ 15 мая 2019

Вот пример:

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

const { a, ...rest } = initObject

Мы опускаем свойство a из объекта, но тогда const a присваивается значение, но оно никогда не используется - ошибка от eslint (no-unused-vars). Можно ли полностью опустить const a?

Ответы [ 7 ]

14 голосов
/ 15 мая 2019

Возможный способ - использовать // 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

JavaScript delete оператор удаляет свойство из объекта

например

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

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

console.log(rest);
7 голосов
/ 15 мая 2019

Это может показаться тривиальным отклонением от @ ответа R3tep , но оно позволяет избежать ловушки маркировки всех переменных в объявлении как используемых:

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

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

Теперь, если restне используется, все равно будет вызывать ошибку eslint.


Что касается вопроса

, каков правильный способ удаления свойства?

Я собираюсь ответить на вопрос, который вы должны были задать вместо этого.Правильный способ обрабатывать объект со свойствами, которые вам не нужны , - переписать вашу логику так, чтобы неявно игнорировал их.

  1. Если вам просто нужны свойства b и c, деструктурируйте только эти свойства:

    const { b, c } = initObject
    

    Даже не признайте, что a существует, если вам это не нужно.

  2. Если у вашего ввода много определенных свойств, с которыми вам нужно иметь дело, и вы не можете предположить, что initObject уже имеет точный макет, в котором он нуждается, тогда избегает соблазна использовать методы отражения или синтаксис, такой как Object.entries(), for...in, расширение объекта и синтаксис отдыха и т. Д.

    Продолжайте обрабатывать конкретные свойства, которые вам нужны, на индивидуальной основе и разбивайте свою логику на разделяемые функции, каждая из которых имеет дело с управляемым подмножеством свойств, если необходимо.

    С другой стороны, если вы можете подготовить свой ввод к havЕсли вам нужен точный макет (например, вы можете предположить, что initObject имеет только b и c), то не стесняйтесь использовать отражение - это именно то, для чего оно нужно.

  3. Если ни один из вышеперечисленных пунктов не относится к вам, и вы все равно обнаружите, что действительно хотите, чтобы initObject имел много произвольных свойств и несколько, которые вы хотите игнорировать, затем вы должны использовать предложение в начале этого ответа (или один из других подходящих для вас ответов).

    Однако, как уже отмечалось, это кодовый запах и индикатор, которыйваша логика должна быть более мягкой с расположением объекта 1 , или ваши предварительные условия для ввода должны измениться 2 .

4 голосов
/ 16 мая 2019

ошибка eslint (no-unused-vars).

Правила no-unused-vars имеют две опции конфигурации, которые помогут в вашем случае использования:

  • Опция ignoreRestSiblings - это логическое значение, по умолчанию false. Когда этот параметр включен, братья и сестры остального свойства игнорируются. Это точно что вам нужно!
  • Опция varsIgnorePattern указывает шаблон регулярного выражения для имен переменных, которые не проверяются на предмет использования. Это позволяет нам сделать исключение для общего символа подчеркивания для явной пометки неиспользуемых переменных с помощью { "varsIgnorePattern": "^_" }.

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

    К сожалению, вам все еще нужно избегать нескольких объявлений переменной _, поэтому, чтобы пропустить несколько свойств, вам нужно сделать что-то вроде { a:_a, b:_b, ...rest } = ….

Можно ли полностью опустить const a?

Плохой хак, который полностью избегает введения какого-либо идентификатора, будет использовать

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

, которая дополнительно разрушает значение свойства .a в объекте, но для этого вам нужно убедиться, что свойство существует и не содержит значения null или undefined.

2 голосов
/ 16 мая 2019

Опция, которая технически удовлетворяет правилам линтера, заключается в объявлении rest авансом, деструктурировании свойства a в rest и , а затем , используя синтаксис 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);

Но все это немного странно.Я бы предпочел настроить / игнорировать линтер или использовать что-то иное, чем деструктурирование, как предлагали другие ответы.

2 голосов
/ 15 мая 2019

Вы можете создать IIFE и передать ему объект.

const initObject = {
  a: 0,
  b: 0,
  c: 0
}
const res = (({a,...rest}) => (a,rest))(initObject);
console.log(res)
1 голос
/ 15 мая 2019

попробуй

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 голос
/ 15 мая 2019

Вы можете создать поверхностную копию объекта с помощью Object.assign() и просто удалить свойство.

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

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

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