首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >程序化解构

程序化解构
EN

Stack Overflow用户
提问于 2018-07-18 18:31:05
回答 2查看 179关注 0票数 4

我有一个不同的用例,在使用解构的概念时,我希望新变量的名称来自不同的变量。

对于ex (通常的解构):

代码语言:javascript
复制
var o = {p: 42, q: true};
var {p: foo, q: bar} = o;
console.log(foo, bar); // Works fine

运行得很好,但是当我尝试用其他变量替换p, foo, q, bar时,我得到了错误,因为我不能得到正确的语法。

我能达到的最接近的是:

代码语言:javascript
复制
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);

其他我试过但不起作用的事情是:

代码语言:javascript
复制
var {[x1]: window[x2], [x3]: bar} = o; //Uncaught SyntaxError: Unexpected token [
var {[x1]: (()=>x2)(), q: bar} = o; //Uncaught SyntaxError: Unexpected token (

但在这里,我仍然不能用x2, x4替换foo, bar

你知道怎样才能做到这一点吗?或者甚至有可能做到这一点?

EN

回答 2

Stack Overflow用户

发布于 2018-07-18 19:01:05

您需要一个左值来赋值,但据我所知,您不能像在let [dynamicName] = value中那样声明动态生成的变量名。但是,对象属性是另一种选择,它可以动态生成:

代码语言:javascript
复制
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);

在全局范围内,您可以滥用全局对象被用作对象环境的事实,并使用window[x2]window[x4],但它在生产代码中并不真正有用。

票数 2
EN

Stack Overflow用户

发布于 2018-07-18 20:03:56

这个问题的答案是完美的in this comment。我会试着用规范的细节来解释。

当我们声明一个变量时,就像这样

代码语言:javascript
复制
var {[x1]: window[x2], [x3]: window[x4]} = o;

为简洁起见,我从规范中删除了所有的下标文本

根据Variable Statement Section,它将遵循以下结果:

代码语言:javascript
复制
VariableStatement:
    var VariableDeclarationList;

VariableDeclarationList:
    VariableDeclaration
    VariableDeclarationList, VariableDeclaration

VariableDeclaration:
    BindingIdentifier Initializer
    BindingPattern Initializer

因为{[x1]: window[x2], [x3]: window[x4]}不是BindingIdentifier,所以它是BindingPattern。生产过程是这样的

代码语言:javascript
复制
BindingPattern:
    ObjectBindingPattern
    ArrayBindingPattern

ObjectBindingPattern:
    {}
    {BindingRestProperty}
    {BindingPropertyList}
    {BindingPropertyList, BindingRestProperty}

...
...

BindingPropertyList:
    BindingProperty
    BindingPropertyList, BindingProperty

...
...

BindingProperty:
    SingleNameBinding
    PropertyName: BindingElement

BindingElement:
    SingleNameBinding
    BindingPattern Initializer

SingleNameBinding:
    BindingIdentifier Initializer

在这种情况下({[x1]: window[x2], [x3]: window[x4]}),生产过程是这样的:BindingPattern -> ObjectBindingPattern -> {BindingPropertyList} -> BindingProperty -> PropertyName: BindingElement -> SingleNameBinding -> BindingIdentifier

在这一点上,window[x2]不是BindingIdentifier。这就是为什么你会得到SyntaxErrorUncaught SyntaxError: Unexpected token [

但它适用于({[x1]: window[x2], [x3]: window[x4]} = o),因为它不再是一个变量声明。它是一个destructuring assignment

生产过程是这样的:

代码语言:javascript
复制
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

在这里,使用CallExpression[Expression]完成了生产。这就是为什么({[x1]: window[x2], [x3]: window[x4]} = o)是有效的,它正在工作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51399729

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档