Jshint weird behavior

I think I should ask a new question about jSHint, the discussion started here , now I see a strange warning from JSHint, I just want to know why.

These services were offered .

So, I have this code in JSHint:

var foo = function() { return { hi: console.log("foo") } //line 15 <------ why we have to put ; here? }; var foo1 = function() { return // i know about ; here, please read post { hi: console.log("foo1") }; // line 22 <---- why we don't need to put ; here? }; 

I marked the lines where I get a warning through the comment "this line" above.

So the question is:

I have 2 strange warnings:

First Warning 15 Missing semicolon. about 15 lines

Second Warning 22 Unnecessary semicolon. about 22 lines

But these 2 lines are looking for me equally, what am I missing? Why do we have 2 different warnings?

EDIT

The question is not about behavior, the question is about warnings. Why are they different?

I know that I missed the semicolon in the second return!

+4
source share
3 answers

Semicolons must follow statements. They do not need to keep track of the blocks. For example, here is an unnecessary semicolon with if :

 if(foo === bar) { //... }; 

A semicolon after an if block if never required.

What does this have to do with your case? Well, sometimes { ... } is a block, and sometimes { ... } is an object literal. The surrounding context allows the grammar to determine what it is. In your first case, this is an object; in the second case, it is a block.

The characters following the return on the same line are parsed as an expression. When { ... } parsed as an expression, it is an object literal. In your first example, return { ... } is a return statement with an object expression. It must have a semicolon because it is a statement.

It is important to understand here that ECMAScript does not allow line breaks to separate return and expression for the return value . This is in ES2015 & # xa7; 11.9.1, Rules for automatic semicolon insertion :

ReturnStatement [Yield] :

  • return [no LineTerminator here] Expression ;
  • return [no LineTerminator here] Expression [In ,? Yield] ;

ReturnStatement cannot have a LineTerminator character between return and expression.

Since you have a newline between your return and { ... } , the { ... } not parsed as belonging to return . It is autonomous, which means that it is analyzed as a block. A sequence { ... } can only be parsed as an object when it is part of a larger statement or expression, for example

  • foo = { ... }
  • function argument ( bar({ ... } )
  • return value ( return { ... } )
  • and etc.

When { ... } is purely on one line, it is treated as a block.

Since the second case has a block, not an object, it does not need a semicolon, as described at the beginning of this answer.

+1
source

Your first example works as you expected. The function will return an object with the hi property. The return includes an optional expression and must be completed with a semicolon (explicit or implicit using an automatic semicolon). JSHint by default prefers explicit semicolons and therefore indicates that you skipped one.

The second example does not work as you might expect. The function will return undefined . The reason for this is because the parser considers that the expression does not follow the return statement. This is due to the fact that the grammar is somewhat ambiguous, which allows you to automatically enter semicolons. This example is parsed as an empty return , followed by a block. Blocks should not end with a semicolon, so JSHint indicates that the semicolon used in the second example is not needed.

+2
source

2 things, firstly, here

 return { hi: console.log("foo") } 

you need to ; indicate the end of the object literal and here

  return { hi: console.log("foo1") }; 

because you did not put { after return , a ; , it is placed there for js engine (optional semicolon).

0
source

Source: https://habr.com/ru/post/1245009/


All Articles