我有一个不同的用例,在使用解构的概念时,我希望新变量的名称来自不同的变量。
对于ex (通常的解构):
var o = {p: 42, q: true};
var {p: foo, q: bar} = o;
console.log(foo, bar); // Works fine
运行得很好,但是当我尝试用其他变量替换p, foo, q, bar时,我得到了错误,因为我不能得到正确的语法。
我能达到的最接近的是:
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);
其他我试过但不起作用的事情是:
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。
你知道怎样才能做到这一点吗?或者甚至有可能做到这一点?
发布于 2018-07-18 19:01:05
您需要一个左值来赋值,但据我所知,您不能像在let [dynamicName] = value中那样声明动态生成的变量名。但是,对象属性是另一种选择,它可以动态生成:
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],但它在生产代码中并不真正有用。
发布于 2018-07-18 20:03:56
这个问题的答案是完美的in this comment。我会试着用规范的细节来解释。
当我们声明一个变量时,就像这样
var {[x1]: window[x2], [x3]: window[x4]} = o;为简洁起见,我从规范中删除了所有的下标文本
根据Variable Statement Section,它将遵循以下结果:
VariableStatement:
var VariableDeclarationList;
VariableDeclarationList:
VariableDeclaration
VariableDeclarationList, VariableDeclaration
VariableDeclaration:
BindingIdentifier Initializer
BindingPattern Initializer因为{[x1]: window[x2], [x3]: window[x4]}不是BindingIdentifier,所以它是BindingPattern。生产过程是这样的
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。这就是为什么你会得到SyntaxError,Uncaught SyntaxError: Unexpected token [。
但它适用于({[x1]: window[x2], [x3]: window[x4]} = o),因为它不再是一个变量声明。它是一个destructuring assignment。
生产过程是这样的:
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)是有效的,它正在工作。
https://stackoverflow.com/questions/51399729
复制相似问题