简体   繁体   English

程序化解构

[英]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 [ . 这就是为什么你得到SyntaxErrorUncaught 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM