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

Javascript 如何在ES6中将结构分解为动态命名的变量?,javascript,ecmascript-6,Javascript,Ecmascript 6,假设我有以下对象: const user = { id: 42, displayName: "jdoe", fullName: { firstName: "John", lastName: "Doe" } }; 我只想要id和fullName 我会这样做: const { id, fullName } = user 很简单,对吧 现在,让我们假设我想根据另一个名为fields的变量的值进行分解 const fields = [ 'id', 'fu

假设我有以下对象:

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

我会这样做:

const { id, fullName } = user
很简单,对吧

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

const fields = [ 'id', 'fullName' ]
现在我的问题是:如何基于密钥数组进行解构?

我不知羞耻地尝试了以下方法,但没有成功:

let{[{……字段}]}=user
let{[……字段]}=user
。有没有办法做到这一点


谢谢

简短的回答:这是不可能的,也不可能

这背后的原因是:它将把新的动态命名变量引入块范围,有效地是动态的
eval
,从而禁用任何性能优化。动态
eval
可以修改fly中的范围,一直被认为是极其危险的,并从ES5严格模式中删除


此外,这将是一种代码气味——引用未定义的变量会抛出
ReferenceError
,因此您需要更多的样板代码来安全地处理这种动态范围。

使用动态键来分解结构并非不可能。为了防止创建动态变量的问题(正如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" }
要解决必须为动态值定义静态别名的问题,可以指定对象的动态特性。在这个简单的示例中,这与恢复整个分解结构是一样的:)

资料来源:


如前所述,如果不使用eval,就无法在JavaScript中分解为动态命名的变量

但您可以使用reduce函数动态获取对象的子集,如下所示:

const destruct=(对象,…键)=>
reduce((a,c)=>({…a[c]:obj[c]}),{});
常量对象={
颜色:“红色”,
尺寸:'大',
金额:10,
};
const subset1=析构函数(对象“颜色”);
const subset2=析构函数(对象“颜色”、“数量”、“大小”);
控制台日志(第1小节);

控制台日志(第2小节)如果不知道键的名称或使用命名变量的别名,则无法进行析构函数

// 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; 
解决方案是使用动态关键点创建对象,如下所示:

const user={
id:42,
显示名称:“jdoe”,
全名:{
名字:“约翰”,
姓:“Doe”
}
};
常量字段=['id','fullName','age'];
const obj=fields.reduce((acc,k)=>({…acc,…(user.hasOwnProperty(k)&&{[k]:user[k]}),{});
for(让k在obj中){
console.log(k,obj[k]);

}
Paul Kögel的答案很好,但我想给出一个更简单的例子,当您只需要动态字段的值,而不需要将其分配给动态键时

设obj={x:3,y:6};
设dynamicField='x';
设{[dynamicField]:value}=obj;

console.log(值)这里有一个关于解构所有属性的相关问题:-这里可能适用相同的答案如果
字段
更改为空数组,那么您将不会创建任何变量,之后的任何代码都将受到危害。将常量与文本一起使用可以确保可以事先确定风险,但类似于
fields=nonliteralvar
的东西会产生问题。这确实是一种代码味道。最终使用了另一种方法。你提出的范围点是无懈可击的。然而,至少有一种情况是,它本身并不是一种代码气味。也就是说,当您有一个函数,它接受一个或多个要在迭代中使用的键时。
省略
删除
减少
的特殊版本都是动态解构有助于提高可读性的情况。在对象中动态分配字段名既是可能的,也是实现代码共享(即更多代码共享)的一种很好的方法。同样,指针的动态分配可以帮助代码干涸,而无需使用hashmap来规避语言限制。不幸的是,您提出的两种解决方案都没有回答所问的问题。变体使用感谢:
// 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;