简体   繁体   English

JSHint奇怪的行为

[英]JSHint strange behavior

I think that i should ask new question about jSHint, discussion started here , i can see now strange warning from JSHint, i just want to know why. 我想我应该问一下关于jSHint的新问题,讨论从这里开始,我现在可以看到来自JSHint的奇怪警告,我只想知道原因。

This services was suggested. 建议提供此服务

So i have this code in JSHint: 所以我在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 lines where i am getting warning via comment "this line" above. 我通过上面的评论“这条线”标记了我正在收到警告的行。

So, question: 所以,问题:

I have 2 strange warnings: 我有两个奇怪的警告:

First warning 15 Missing semicolon. 第一次警告15 Missing semicolon. about 15 line 约15行

Second warning 22 Unnecessary semicolon. 第二次警告22 Unnecessary semicolon. about 22 line 约22行

But those 2 lines looks for me identical, what am i missing? 但是这两行看起来相同,我缺少什么? why we have 2 different warnings here? 为什么我们在这里有两个不同的警告?

EDIT 编辑

Question is not about behavior, question is about warnings. 问题不是关于行为,问题是关于警告。 Why are they different? 他们为什么不同?

I know that i missed semicolon in second return! 我知道我在第二次回归中错过了分号!

Your first example runs in the way you would expect. 您的第一个示例以您期望的方式运行。 The function will return an object with the hi property. 该函数将返回具有hi属性的对象。 The return statement includes an optional expression and must be terminated by a semicolon (either explicit or implicit via automatic semicolon insertion). return语句包含一个可选表达式,必须以分号结尾(通过自动分号插入显式或隐式)。 JSHint by default prefers explicit semicolons and therefore points out that you've missed one. 默认情况下,JSHint更喜欢显式分号,因此指出你错过了一个分号。

Your second example does not run in the way you may expect. 你的第二个例子没有以你预期的方式运行。 The function will return undefined . 该函数将返回undefined The reason for this is that the parser believes the return statement is not followed by an expression. 原因是解析器认为return语句后面没有表达式。 This is because the grammar is somewhat ambiguous to allow for automatic semicolon insertion. 这是因为语法有点模糊,不允许自动分号插入。 This example is parsed as an empty return statement followed by a block. 此示例被解析为空return语句,后跟块。 Blocks do not need to be terminated by a semicolon, hence JSHint points out that the semicolon used in your second example is unnecessary. 块不需要以分号结束,因此JSHint指出第二个示例中使用的分号是不必要的。

Semicolons should follow statements . 分号应遵循陈述 They do not need to follow blocks . 他们不需要跟随障碍 For example, here's an unnecessary semicolon with if : 例如,这是一个不必要的分号, if

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

The semicolon after the if block is never necessary. if块之后的分号是绝对必要的。

What does this have to do with your case? 这跟你的情况有什么关系? Well, sometimes { ... } is a block, and sometimes { ... } is an object literal. 好吧,有时{ ... }是一个块,有时{ ... }是一个对象文字。 The surrounding context lets the grammar determine which it is. 周围的上下文让语法确定它是什么。 In your first case, it's a an object; 在你的第一种情况下,它是一个对象; in the second case, it's a block. 在第二种情况下,它是一个块。

The characters following a return statement on the same line are parsed as an expression. 同一行上的return语句后面的字符被解析为表达式。 When { ... } is parsed as an expression, it is an object literal. { ... }被解析为表达式时,它是一个对象文字。 In your first example, return { ... } is a return statement with an object expression. 在第一个示例中, return { ... }是一个带有对象表达式的return语句。 It should have a terminating semicolon, because it is a statement. 它应该有一个终止分号,因为它是一个声明。

The critical thing to understand here is that the ECMAScript grammar doesn't allow a line break to separate return and its return-value expression . 这里要理解的关键是ECMAScript语法不允许换行符将return及其返回值表达式分开 It's in ES2015 §11.9.1, Rules of Automatic Semicolon Insertion : 符合ES2015§11.9.1,自动分号插入规则

ReturnStatement [Yield] : ReturnStatement [收益率]

  • return [no LineTerminator here] Expression ; return [此处没有LineTerminator ] 表达式 ;
  • return [no LineTerminator here] Expression [In, ?Yield] ; return [no LineTerminator here] Expression [In,?Yield] ;

A ReturnStatement can't have a LineTerminator character between the return and the Expression . ReturnStatementreturnExpression之间不能有LineTerminator字符。

Since you do have a newline character between your return and the { ... } , the { ... } part is not parsed as belonging to the return . 由于在return{ ... }之间确实有换行符,因此{ ... }部分不会被解析为属于return It is standalone, which means it is a parsed as a block. 它是独立的,这意味着它被解析为块。 The { ... } sequence can only be parsed as an object when it is part of a larger statement or expression, like { ... }序列只有当它是较大的语句或表达式的一部分时才能被解析为对象,例如

  • assignment, foo = { ... } 赋值, foo = { ... }
  • function argument ( bar({ ... } ) 函数参数( bar({ ... }
  • a return value ( return { ... } ) 返回值( return { ... }
  • etc. 等等

When { ... } is purely on a line by itself, 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. 由于第二种情况有一个块而不是一个对象,因此它不需要分号,如本答案开头所述。

2 things, firstly here 2件事,首先在这里

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

you need ; 你需要; to specify end of object literal and here 指定对象文字的结尾和这里

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

because you didn't put { after return , a ; 因为你没有把{ return后,a ; it is put there for you by js engine (optional semicolon). 它由js引擎(可选分号)放在那里。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM