1

It's often possible to surround code in brackets, which can be useful when creating comma expressions.

Why does the code below have syntax errors when surrounding certain code with brackets?

let o = {a: 2, b: 3}

console.log('hello')    // works
(console.log('hello'))  // works

{console.log('hello')}    // works
({console.log('hello')})  // colon or comma expected

for(const k in o) console.log(k)      // works
(for(const k in o) console.log(k))    // error: newline or semicolon expected

for(const k in o) {console.log(k)}    // works
(for(const k in o) {console.log(k)})  // error: statement expected
Andrew Parks
  • 6,358
  • 2
  • 12
  • 27
  • Unless you're knowledgeable enough to avoid the pitfalls of ASI, use semicolons. Even if you understand ASI, it could be a good idea to use semicolons anyway. – CertainPerformance Dec 05 '22 at 06:48
  • @CertainPerformance Thanks, I read the linked question, but I'm still confused: are you saying that javascript is failing to insert semicolons? If so, how can I add semicolons to fix this? Or are you saying that javascript is automatically inserting semicolons where they shouldn't be? – Andrew Parks Dec 05 '22 at 06:51
  • You are not ending the statements where you think you are, even though they're on separate lines, because semicolons are not being automatically inserted - better not to rely on ASI to always do things as you're expecting it to, be explicit and you won't be surprised. – CertainPerformance Dec 05 '22 at 06:58
  • @CertainPerformance I'm having difficulty reconciling your comment with the specifics of why this won't work, even if it's the entirety of the code: `let o = {a: 2, b: 3}; (for(const k in o) console.log(k))`. Now there is only one line. I don't think you've explained exactly where the problem is... – Andrew Parks Dec 05 '22 at 07:01
  • Ah, the snippet in the question produces errors due to ASI, so I thought that's what the issue you were asking about was – CertainPerformance Dec 05 '22 at 07:03

1 Answers1

1

for constructs are statements. Statements are parts of the language that do something - such as declare a variable, or conditionally run a block, or start a loop.

In contrast, some things are expressions, which evaluate to a value. Your {a: 2, b: 3} is an example of something that can be evaluated as an object literal, an expression. console.log calls (and all function calls) are also expressions; they evalute to values.

Statements can't evaluate to values because a statement does something on its own, and interpreting it as a value as part of something else just doesn't make sense. Putting something inside of parentheses will only be syntactically valid if that "something" is an expression; if it's a statement as well, then it can't be evaluated to a value. For similar reasons, none of the following lines are valid:

const val1 = (if (true) {});
const val2 = (const foo = 'foo';);
const val3 = (while(false) {});
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320