Как разрушить динамически названные переменные в ES6?

Предположим, что у меня есть следующий объект:

const user = { 
  id: 42, 
  displayName: "jdoe",
  fullName: { 
      firstName: "John",
      lastName: "Doe"
  }
};

И я хочу только id и fullName.

Я сделаю следующее:

const { id, fullName } = user

Легко-peasy, правильно?

Теперь предположим, что я хочу выполнить деструктурирование на основе значения другой переменной, называемой fields.

const fields = [ 'id', 'fullName' ]

Теперь мой вопрос: Как я могу выполнить деструктурирование на основе массива ключей?

Я бесстыдно пробовал следующее без успеха:

let {[{...fields}]} = user и let {[...fields]} = user. Есть ли способ сделать это?

Спасибо

Ответ 1

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

const user = { 
  id: 42, 
  displayName: "jdoe",
  fullName: { 
      firstName: "John",
      lastName: "Doe"
  }
};

const fields = [ 'id', 'fullName' ];
const object = {};

const {[fields[0]]: id, [fields[1]]: fullName} = user;

console.log(id); // 42
console.log(fullName); // { firstName: "John", lastName: "Doe" }

Чтобы обойти проблему определения статических псевдонимов для динамических значений, вы можете назначить динамические свойства объекта. В этом простом примере это то же самое, что и восстановление всего деструктурирования:)

const user = { 
  id: 42, 
  displayName: "jdoe",
  fullName: { 
      firstName: "John",
      lastName: "Doe"
  }
};

const fields = [ 'id', 'fullName' ];
const object = {};

({[fields[0]]: object[fields[0]], [fields[1]]: object[fields[1]]} = user);

console.log(object.id); // 42
console.log(object.fullName); // { firstName: "John", lastName: "Doe" }

Источники:

Ответ 2

Короткий ответ: это невозможно, и это будет невозможно.

Учитывая это: он вводит новые динамически именованные переменные в область блока, фактически будучи динамическим eval, тем самым отменяя любую оптимизацию производительности. Динамический eval, который может изменять масштаб в мухе, всегда считался чрезвычайно опасным и был удален из строкового режима ES5.

Кроме того, это был бы запах кода, ссылающийся на undefined variables throws ReferenceError, поэтому для безопасного управления такой динамической областью вам понадобится больше кода шаблона.

Ответ 3

Как уже говорилось ранее, вы не можете перейти на динамически именованные переменные в JavaScript без использования eval.

Но вы можете получить подмножество объекта динамически, используя функцию Reduce следующим образом:

const destruct = (obj, ...keys) => 
  keys.reduce((a, c) => ({ ...a, [c]: obj[c] }), {});

const object = { 
  color: 'red',
  size: 'big',
  amount: 10,
};

const subset1 = destruct(object, 'color');
const subset2 = destruct(object, 'color', 'amount');
const subset3 = destruct(object, 'color', 'amount', 'size');
console.log(subset1);
console.log(subset2);
console.log(subset3);