Как разрушить динамически названные переменные в 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);