问题
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)
回答1:
This 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());
回答2:
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
回答3:
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 comparison, 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.
来源:https://stackoverflow.com/questions/51003328/having-semicolon-after-spread-syntax-jn-javascript-breaks-execution-with-error