如何在ES6中将结构化为动态命名的变量?

时间:2016-03-11 11:36:57

标签: javascript ecmascript-6

假设我有以下对象:

const user = { 
  id: 42, 
  displayName: "jdoe",
  fullName: { 
      firstName: "John",
      lastName: "Doe"
  }
};

我只想要idfullName

我将执行以下操作:

const { id, fullName } = user

轻松,对吧?

现在让我们假设我想根据另一个名为fields的变量的值进行解构。

const fields = [ 'id', 'fullName' ]

现在我的问题是:如何根据一系列密钥进行解构?

我无耻地尝试了以下但没有成功:

let {[{...fields}]} = userlet {[...fields]} = user。有什么方法可以做到这一点吗?

谢谢

5 个答案:

答案 0 :(得分:19)

使用动态密钥进行结构化并非不可能。为了防止创建动态变量的问题(如Ginden所提到的),您需要提供别名。

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

来源:

答案 1 :(得分:5)

简短回答:这是不可能的,但它不可能。

这背后的推理:它会将新的动态命名变量引入块范围,实际上是动态eval,从而禁用任何性能优化。可以在fly中修改范围的动态eval始终被视为非常危险,并且已从ES5严格模式中删除。

此外,它会引起代码异味 - 引用未定义的变量抛出ReferenceError,因此您需要更多的样板代码来安全地处理这样的动态范围。

答案 2 :(得分:4)

如前所述,您无法在不使用eval的情况下在JavaScript中破坏动态命名的变量。

但是您可以使用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', 'size');
console.log(subset1);
console.log(subset2);




答案 3 :(得分:4)

Paul Kögel 的回答很棒,但我想举一个更简单的例子,说明当您只需要动态字段的值但不需要将其分配给动态键时。

let obj = {x: 3, y: 6};
let dynamicField = 'x';

let {[dynamicField]: value} = obj;

console.log(value);

答案 4 :(得分:1)

在不知道键名或为命名变量使用别名的情况下无法破坏

// 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]);
}