Как разложить на динамически именованные переменные в 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"
  }
};
  1. используя объект "Object.key", "forEach" и "window".

            Object.keys(user).forEach(l=>window[l]=user[l]);
    
  2. Просто используя Object. метод назначения.

            Object.assign(window, user)
    

Выход:

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

В любом случае, я новичок в JS. Так что не обижайтесь, если вы нашли в моем ответе вводящую в заблуждение информацию.

Другие вопросы по тегам