Spreading into declared variables (Having semicolon after spread syntax in JavaScript breaks execution with error "Unex

Can someone explain me whyconst getabc = ()=> ({a:'aa',b:'bb',c:123});let a, b,

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
 |  Show 1 more ment

3 Answers 3

Reset to default 7

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());

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条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信