Деструктуризация объекта для структурирования нового объекта

У меня есть объект, исходящий от API-ответа, выглядит так:

{
  // ...
  customerName: 'Jake',
  customerUserName: 'jak3',
  customerEmail: 'some@email.com',
  // ...
}

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

{
  name: 'Jake',
  userName: 'jak3',
  email: 'some@email.com'
}

я знаю, что могу сделать это, используя Object.assign() как это:

let apiUser = {};
Object.assign(apiUser, {
  name: response.customerName || 'John Doe', // customerName may be an empty string
  userName : response.customerUserName,
  email: response.customerEmail
});

Наконец, вопрос: могу ли я сделать это путем разрушения объекта? Я уже попробовал:

let apiUser = {};
{customerName: apiUser.name, customerUserName: apiUser.userName, customerEmail: apiUser.email} = response;

но бросили и SyntaxError: Unexpected token : Есть ли правильный синтаксис или я должен придерживаться Object.assign()? И, пожалуйста, не забывайте условие "Джон Доу".

4 ответа

Решение

Это работает так, как вы ожидаете:

let response = {
  // ...
  customerName: 'Jake',
  customerUserName: 'jak3',
  customerEmail: 'some@email.com',
  // ...
};


// Destructuring Assignment (w/ default value)
let apiUser = {};
({ customerName:     apiUser.name = 'John Doe', //<-- default value with '='
   customerUserName: apiUser.userName, 
   customerEmail:    apiUser.email
 } = response );


// Assign Prototype Method
/*
let apiUser = {};
Object.assign(apiUser, {
  name: response.customerName || 'John Doe', // customerName may be an empty string
  userName : response.customerUserName,
  email: response.customerEmail
});
*/

console.log(apiUser);

В соответствии с документацией о назначении MDN без декларации:

( .. ) Вокруг оператора присваивания требуется синтаксис при использовании объекта литерала с деструктуризацией присваивания без объявления.

{a, b} = {a: 1, b: 2} недопустим автономный синтаксис, так как {a, b} в левой части рассматривается блок, а не объектный литерал.

Тем не мение, ({a, b} = {a: 1, b: 2}) действителен, как и var {a, b} = {a: 1, b: 2}

ПРИМЕЧАНИЕ: ваш ( ..) Перед выражением должна стоять точка с запятой, или оно может использоваться для выполнения функции в предыдущей строке.


Примечание. Как Object.Assign, так и деструктурированные назначения в общем случае недоступны в Internet Explorer (Edge - это отдельная история). Примите это во внимание для вашей реализации.

Почему бы просто не присвоить новую переменную, избавившись от предварительного назначения с помощью let а затем изменив переменную:

const apiUser = {
  name: response.customerName || 'John Doe',
  userName : response.customerUserName,
  email: response.customerEmail
};

Или, если вы хотите добавить к уже существующим полям:

const apiUser = Object.assign({}, originalObject, {
  name: response.customerName || 'John Doe',
  userName : response.customerUserName,
  email: response.customerEmail
}

Это также должно работать:

const { customerName: name, customerUserName: userName, customerEmail: email } = originalObject;
const apiUser = {
  name,
  userName,
  customerEmail
};

Ваш последний пример хорош, вам просто нужно обернуть символы в скобки следующим образом:

({customerName: apiUser.name, customerUserName: apiUser.userName, customerEmail: apiUser.email} = response)

однако это не позволит вам сделать условное значение. Для этого вам нужно будет использовать Object.assign или один из других методов, которые вы обсуждали.

РЕДАКТИРОВАТЬ

Оказывается, вы можете сделать условное значение!

({customerName: apiUser.name = "John Doe", customerUserName: apiUser.userName, customerEmail: apiUser.email} = response)

Вы могли бы сделать что-то вроде:

let response = {
    CustomerName: '',
    CustomerUsername: 'jak3',
    CustomerEmail: 'some@email.com',
};
let apiUser = {
    Name: '',
    Username: '',
    Email: '',
};

(
    [
        apiUser.Name,
        apiUser.Username,
        apiUser.Email
    ] = [
        response.CustomerName || 'John Doe',
        response.CustomerUsername,
        response.CustomerEmail
    ]
);
console.log(apiUser);

Однако я не уверен, как это улучшение читабельности по сравнению с тем, чтобы не использовать какую-либо необычную функцию, а просто делать:

let response = {
    CustomerName: '',
    CustomerUsername: 'jak3',
    CustomerEmail: 'some@email.com',
};
let apiUser = {
    Name: response.CustomerName || 'John Doe',
    Username: response.CustomerUsername,
    Email: response.CustomerEmail,
};
console.log(apiUser);

Конечно, это легче читать и понимать? Есть ли какая-то конкретная причина, почему вы пытаетесь использовать более эзотерический синтаксис для достижения этой цели?

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