[英]Programmatic Destructuring
I have a different use case in which when using the concept of destructuring I want the name of new variable to come from different variables. 我有一个不同的用例,当使用解构的概念时,我希望新变量的名称来自不同的变量。
For ex (usual destructuring): 对于前(通常的解构):
var o = {p: 42, q: true}; var {p: foo, q: bar} = o; console.log(foo, bar); // Works fine
Is working fine but when I try to replace p, foo, q, bar
with some other variable I get the error because I can not get the syntax right. 工作正常,但当我尝试用其他变量替换p, foo, q, bar
,我得到错误,因为我无法正确获得语法。
The closest I have reached is: 我最接近的是:
var o = {p: 42, q: true}; var x1 = "p"; var x2 = "foo"; var x3 = "q"; var x4 = "bar"; var {[x1]: foo, [x3]: bar} = o; console.log(foo, bar);
Othe things which I tried but didnt work are: 我试过但没有用的东西是:
var {[x1]: window[x2], [x3]: bar} = o; //Uncaught SyntaxError: Unexpected token [
var {[x1]: (()=>x2)(), q: bar} = o; //Uncaught SyntaxError: Unexpected token (
But here I am still not able to replace foo, bar
with x2, x4
. 但是在这里我仍然无法用x2, x4
取代foo, bar
。
Any idea how can one achieve this? 任何想法如何实现这一目标? Or is it even possible to do this? 或者甚至可以这样做?
You need an lvalue to assign to, but from what i know, you cannot declare dynamically generated variable names, as in let [dynamicName] = value
. 你需要一个左值来分配,但据我所知,你不能声明动态生成的变量名,如let [dynamicName] = value
。 However, object properties are an alternative, which can dynamically be generated: 但是,对象属性是一种替代方法,可以动态生成:
var o = {p: 42, q: true}; var container = {}; var x1 = "p"; var x2 = "foo"; var x3 = "q"; var x4 = "bar"; ({[x1]: container[x2], [x3]: container[x4]} = o); console.log(container.foo, container.bar);
On global scope, you can abuse the fact that the global object is being used as object environment, and use window[x2]
and window[x4]
, but it's not really useful in production code. 在全局范围内,您可以滥用全局对象用作对象环境的事实,并使用window[x2]
和window[x4]
,但它在生产代码中并不常用。
It was answered perfectly in this comment . 这篇评论得到了很好的回答。 I'll try to explain with the specification details. 我将尝试解释规范细节。
When we declare a variable, like this 当我们声明一个变量时,就像这样
var {[x1]: window[x2], [x3]: window[x4]} = o;
I removed all the subscripted text from the spec for brevity 为简洁起见,我从规范中删除了所有下标文本
it would follow the following production as per Variable Statement Section , 按照变量声明部分 ,它将遵循以下生产,
VariableStatement:
var VariableDeclarationList;
VariableDeclarationList:
VariableDeclaration
VariableDeclarationList, VariableDeclaration
VariableDeclaration:
BindingIdentifier Initializer
BindingPattern Initializer
As {[x1]: window[x2], [x3]: window[x4]}
is not a BindingIdentifier
, it is a BindingPattern
. 由于{[x1]: window[x2], [x3]: window[x4]}
不是BindingIdentifier
,它是BindingPattern
。 And that production goes like this 那个产品是这样的
BindingPattern:
ObjectBindingPattern
ArrayBindingPattern
ObjectBindingPattern:
{}
{BindingRestProperty}
{BindingPropertyList}
{BindingPropertyList, BindingRestProperty}
...
...
BindingPropertyList:
BindingProperty
BindingPropertyList, BindingProperty
...
...
BindingProperty:
SingleNameBinding
PropertyName: BindingElement
BindingElement:
SingleNameBinding
BindingPattern Initializer
SingleNameBinding:
BindingIdentifier Initializer
In this case ( {[x1]: window[x2], [x3]: window[x4]}
), the production goes like this BindingPattern
-> ObjectBindingPattern
-> {BindingPropertyList}
-> BindingProperty
-> PropertyName: BindingElement
-> SingleNameBinding
-> BindingIdentifier
. 在这种情况下( {[x1]: window[x2], [x3]: window[x4]}
),生产就像这样BindingPattern
- > ObjectBindingPattern
- > {BindingPropertyList}
- > BindingProperty
- > PropertyName: BindingElement
- > SingleNameBinding
- > BindingIdentifier
。
At this point, window[x2]
is not a BindingIdentifier
. 此时, window[x2]
不是BindingIdentifier
。 That is why you are getting the SyntaxError
, Uncaught SyntaxError: Unexpected token [
. 这就是为什么你得到SyntaxError
, Uncaught SyntaxError: Unexpected token [
。
But it works in case of ({[x1]: window[x2], [x3]: window[x4]} = o)
because, it is not a variable declaration anymore. 但它适用于({[x1]: window[x2], [x3]: window[x4]} = o)
因为它不再是变量声明。 It is a destructuring assignment . 这是一个解构任务 。
Production for that goes like this 生产就是这样的
AssignmentPattern:
ObjectAssignmentPattern
ArrayAssignmentPattern
ObjectAssignmentPattern:
{}
{AssignmentRestProperty}
{AssignmentPropertyList}
{AssignmentPropertyList, AssignmentRestProperty}
AssignmentPropertyList:
AssignmentProperty
AssignmentPropertyList, AssignmentProperty
AssignmentProperty:
IdentifierReference Initializer
PropertyName: AssignmentElement
AssignmentElement:
DestructuringAssignmentTarget Initializer
DestructuringAssignmentTarget:
LeftHandSideExpression
LeftHandSideExpression:
NewExpression
CallExpression
CallExpression:
CoverCallExpressionAndAsyncArrowHead
SuperCall
CallExpression Arguments
CallExpression[Expression]
CallExpression.IdentifierName
CallExpression TemplateLiteral
Here the production is complete with CallExpression[Expression]
. 这里的制作完成了CallExpression[Expression]
。 That is why ({[x1]: window[x2], [x3]: window[x4]} = o)
is valid and it is working. 这就是为什么({[x1]: window[x2], [x3]: window[x4]} = o)
有效并且它正在工作的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.