假设我有以下对象:
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
我只想要id
和fullName
。
我将执行以下操作:
const { id, fullName } = user
轻松,对吧?
现在让我们假设我想根据另一个名为fields
的变量的值进行解构。
const fields = [ 'id', 'fullName' ]
现在我的问题是:如何根据一系列密钥进行解构?
我无耻地尝试了以下但没有成功:
let {[{...fields}]} = user
和let {[...fields]} = user
。有什么方法可以做到这一点吗?
谢谢
答案 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]);
}