Can someone explain me why
const getabc = ()=> ({a:'aa',b:'bb',c:123});
let a, b, c;
{ a, b, c } = {...getabc()}
Can someone explain me why
const getabc = ()=> ({a:'aa',b:'bb',c:123});
let a, b, c;
{ a, b, c } = {...getabc()}
this works
and
const getabc = ()=> ({a:'aa',b:'bb',c:123});
let a, b, c;
{ a, b, c } = {...getabc()};
this does not (note semicolon at the end)
Share Improve this question edited Feb 26, 2023 at 20:19 DevThiman 1,1381 gold badge14 silver badges28 bronze badges asked Jun 23, 2018 at 17:02 Andrey PutilovAndrey Putilov 1434 silver badges13 bronze badges 6- 3 why spreading? it is superfluous. – Nina Scholz Commented Jun 23, 2018 at 17:06
- 1 @NinaScholz stackoverflow./help/mcve This is a minimum example. – Raymond Chen Commented Jun 23, 2018 at 17:07
-
First one doesn't work on Firefox, got
SyntaxError: expected expression, got '='
– Jorjon Commented Jun 23, 2018 at 17:10 - 1 @RaymondChen, what have i to do with mcve? the object is generated with another object. the generated object is used for destructuring and never used again. the properties are transfered. so it is superfluous. – Nina Scholz Commented Jun 23, 2018 at 17:10
- 1 Both of them produce an error in Chrome. – JLRishe Commented Jun 23, 2018 at 17:20
3 Answers
Reset to default 7This has nothing to do with spread syntax or semicolons.
Object destructuring assignments that are not preceded with something like var
, const
, or let
must use parentheses (or in some other way occur as a an expression within a larger statement containing it) because otherwise JS will parse the opening brace as the beginning of a block:
const getabc = ()=>({a:'aa',b:'bb',c:123});
let a, b, c;
({ a, b, c } = {...getabc()});
At the same time, there is no point in using spread syntax here, so you can remove that:
const getabc = ()=>({a:'aa',b:'bb',c:123});
let a, b, c;
({ a, b, c } = getabc());
You are missing the parentheshis, as per MDN documentation:
A variable can be assigned its value with destructuring separate from its declaration.
var a, b; ({a, b} = {a: 1, b: 2});
const getabc = ()=>({a:'aa',b:'bb',c:123});
let a, b, c;
({ a, b, c } = {...getabc()});
console.log(a,b,c);
My guess is that the first one is an error in Chrome implementation, since Firefox throws an error.
Chrome
Firefox
This is an artefact of Chrome's hidden way of helping developers. Namely it will auto-wrap certain expressions in parentheses (or evaluate them as if wrapped, there is no difference) so
{a} = {a: true}
is actually evaluated as if
({a} = {a: true})
The first one is not a valid statement, however, since the {}
is evaluated as a code block - the same construct as if (cond) {}
or for() {}
or function() {}
, instead of an object literal syntax or an object destructuring syntax.
Should be noted that this is the correct interpretation of the code - it should throw a syntax error because it's not valid:
{a} = {a: true}
adding parentheses can be done in to avoid the starting {
being interpreted as a code block:
({a} = {a: true})
console.log(a);
Chrome's console hides that away from you. For parison, Firefox also produces the same result - an error.
However, when you add a semicolon, then the expression stops being valid for parentheses: ({a} = {a: true};)
makes no sense, so Chrome evaluates it exactly as written which is also the correct interpretation in both cases:
{a} = {a: true};
This behaviour is only present in V8 related REPL environments. The same can be observed in Opera or a Node.JS REPL, for example. When evaluating code which is in a normal context and not the REPLs regular parsing rules are used and the expression {a} = {a: true}
throws an error. See here on repl.it or test at another place
- create a file that contains
{a} = {a: true}
and execute it via node (middle panel in repl.it) - entering the same code in a node REPL (right panel in repl.it)
In case you wonder "why not just ignore the code blocks in the general case", that will potentially lead to errors or at the very least confusing grammar. For example, this is valid code which uses code blocks:
let a = 1;
{
let a = 2;
console.log("inside block", a);
}
console.log("outside block", a);
Treating the {
and }
as anything other than a code block would be a problem.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744833890a4596144.html
评论列表(0条)