Consider the following code:
let [circleTranslateX, circleTranslateY, circleScale] = [this.state.pan.x, this.state.pan.y, this.state.scale];
let circleTransform = [
{circleTranslateX},
{circleTranslateY},
{scale: circleScale}
];
The above works fine, but if I change the line:
{circleTranslateX}
To:
{this.state.pan.x}
I get an Unexpected token
error. Why is this so, if the code should be equivalent before destructuring?
{circleTranslateX}
// valid because it could be re-written as:
// {circleTranslateX: circleTranslateX}
{this.state.pan.x}
// would be akin to:
// {this.state.pan.x: this.state.pan.x}
// which isn't valid object initialisation
// because this.state.pan.x isn't a valid
// object key
This is due to ECMAScript 2015's new object shorthand property declarations. If you want to learn more about how this works, you can look at the language specification. Per the language specification on Object Initializers, Section 12.2.6 :
Syntax
ObjectLiteral : { } { PropertyDefinitionList } { PropertyDefinitionList , }
Where PropertyDefinitionList
is defined as:
PropertyDefinitionList : PropertyDefinition PropertyDefinitionList , PropertyDefinition
And PropertyDefinition
is:
PropertyDefinition : IdentifierReference CoverInitializedName PropertyName : AssignmentExpression MethodDefinition
Thus, an object literal can contain property definitions, which are one of: IdentifierReference
(the one that is relevant here), CoverInitializedName
, PropertyName : AssignmentExpression
, or MethodDefinition
.
The new shorthand syntax is defined by the line where IdentifierReference
is defined as one of the options for a PropertyDefinition
. That means a property definition can just be an identifier reference and the property name will be string value of the reference and the property value, the result of evaluating the reference, see Section 12.2.6.9 , second paragraph.
The problem comes in when you look at the definition of identifiers, Section 12.1 :
Syntax
IdentifierReference : Identifier
[...]
Identifier : IdentifierName but not ReservedWord
Where IdentifierName
is just the identifier's name (variables name) and ReservedWord
is a reserved keyword.
Now, to apply this to your current example. When you do {circleTranslateX}
, it's perfectly valid because circleTranslateX
is an Identifier
(you destruct it earlier) and thus IdentifierReference
. This matches the syntax for a property definition and is valid. It's comparable to:
{
circleTranslateX: circleTranslateX
}
Which is also valid. On the contrary, your second example {this.state.pan.x}
is invalid. This is because this.state.pan.x
is not a valid IdentifierName
, thus not a valid identifier or identifier reference. That means it does not match the syntax for an object literal and is thus invalid. It's not seen as an object by the engine so your attempt at an object literal results in an unexpected token. It's also comparable to (if it were even treated as an object):
{
this.state.pan.x: this.state.pan.x
}
This is of course invalid because you can't have dots in property names.
Although, you could use ECMAScript 2015 Compute: Property Names which allow for expressions as property names if enclosed in square brackets:
{
[this.state.pan.x]: this.state.pan.x
}
But I really see no point if you use array destructuring earlier to get circleTranslateX
.
Further reading with Object Initializers at MDN .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.