Как разложить на динамически именованные переменные в 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
, Есть ли способ сделать это?
Спасибо
6 ответов
Это не невозможно разрушить с помощью динамического ключа. Чтобы предотвратить проблему создания динамических переменных (как упоминал Гинден), вы должны предоставить псевдонимы.
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" }
источники:
Ответ Пола Кегеля великолепен, но я хотел привести более простой пример, когда вам нужно только значение динамического поля, но не нужно назначать его динамическому ключу.
Краткий ответ: это невозможно и не будет возможно.
Причина этого заключается в том, что он будет вводить новые динамически именуемые переменные в область видимости блока, фактически будучи динамическим eval
, таким образом отключая любую оптимизацию производительности. динамический eval
который может изменять область видимости в fly, всегда считался чрезвычайно опасным и был удален из строгого режима ES5.
Более того, это будет запах кода - ссылки на неопределенные переменные ReferenceError
, так что вам нужно больше шаблонного кода для безопасной обработки такой динамической области.
Как уже говорилось ранее, вы не можете преобразовать динамически именованные переменные в JavaScript без использования eval.
Но вы можете получить подмножество объекта динамически, используя функцию Reduce следующим образом:
const destruct = (keys, obj) =>
keys.reduce((a, c) => ({ ...a, [c]: obj[c] }), {});
const object = {
color: 'red',
size: 'big',
amount: 10,
};
const subset = destruct(['color', 'amount'], object);
console.log(subset);
Вы не можете разрушить, не зная имени ключей или используя псевдоним для именованных переменных
// you know the name of the keys
const { id, fullName } = user;
// use an alias for named variables
const { [fields[0]]: id, [fields[1]]: fullName } = user;
Решение - использовать Array.reduce()
чтобы создать объект с такими динамическими клавишами:
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
const fields = [ 'id', 'fullName', 'age' ];
const obj = fields.reduce((acc, k) => ({ ...acc, ...(user.hasOwnProperty(k) && { [k]: user[k] }) }), {});
for(let k in obj) {
console.log(k, obj[k]);
}
Я считаю, что приведенные выше ответы интеллектуальны и действительны, потому что все они даны профессиональными разработчиками. :). Но я нашел небольшое и эффективное решение для динамической деструктуризации любых объектов. вы можете разрушить их двумя способами. Но оба способа проделали одно и то же действие. Бывший:
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
используя объект "Object.key", "forEach" и "window".
Object.keys(user).forEach(l=>window[l]=user[l]);
Просто используя Object. метод назначения.
Object.assign(window, user)
Выход:
console.log(id, displayName, fullName)
// 42 jdoe {firstName: "John", lastName: "Doe"}
В любом случае, я новичок в JS. Так что не обижайтесь, если вы нашли в моем ответе вводящую в заблуждение информацию.