用于构造新对象的对象解构

Object destructuring for structuring a new object

我有一个来自 API 回复的对象,看起来像这样:

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

我想声明一个新对象 named 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()?请不要忘记 "John Doe" 条件。

你的最后一个例子很好,你只需要像这样用括号括起来:

({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 的前期赋值,然后修改变量:

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
};

它如您所愿地工作:

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 documentation of Assignment without declaration:

The ( .. ) around the assignment statement is required syntax when using object literal destructuring assignment without a declaration.

{a, b} = {a: 1, b: 2} is not valid stand-alone syntax, as the {a, b} on the left-hand side is considered a block and not an object literal.

However, ({a, b} = {a: 1, b: 2}) is valid, as is var {a, b} = {a: 1, b: 2}

NOTE: Your ( ..) expression needs to be preceded by a semicolon or it may be used to execute a function on the previous line.


注意: Object.Assign 和解构赋值在 Internet Explorer 中基本上不可用(Edge 是另一回事)。在您的实施中考虑到这一点。

你可以这样做:

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);

这肯定更容易阅读和理解吗?您尝试使用更深奥的语法来实现此目的有什么具体原因吗?