我认为我应该问一个关于jSHint的新问题,讨论开始here,我现在可以看到来自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?
};
我通过上面的评论“此行”标记了我收到警告的行。
所以,问:
我有两个奇怪的警告:
首先警告15 Missing semicolon.
约15行
第二次警告22 Unnecessary semicolon.
约22行
但那两行代表我相同,我缺少什么?为什么我们在这里有两个不同的警告?
修改
问题与行为无关,问题与警告有关。他们为什么不同?
我知道我在第二次回归中错过了分号!
答案 0 :(得分:2)
您的第一个示例以您期望的方式运行。该函数将返回具有hi
属性的对象。 return
语句包含一个可选表达式,必须以分号结尾(通过自动分号插入显式或隐式)。默认情况下,JSHint更喜欢使用明确的分号,因此指出您错过了分号。
你的第二个例子没有以你预期的方式运行。该函数将返回undefined
。原因是解析器认为return
语句后面没有表达式。这是因为语法有点模糊,不允许自动分号插入。此示例被解析为空return
语句,后跟一个块。块不需要以分号结束,因此JSHint指出第二个示例中使用的分号是不必要的。
答案 1 :(得分:2)
分号应遵循语句。他们不需要关注块。例如,这是一个带有if
的不必要的分号:
if(foo === bar) {
//...
};
if
阻止后的分号是绝对必要的。
这与您的案件有什么关系?好吧,有时{ ... }
是一个块,有时{ ... }
是一个对象文字。周围的上下文让语法确定它是什么。在你的第一种情况下,它是一个对象;在第二种情况下,它是一个块。
同一行上return
语句后面的字符被解析为表达式。当{ ... }
被解析为表达式时,它是一个对象文字。在第一个示例中,return { ... }
是带有对象表达式的return语句。它应该有一个终止分号,因为它是一个声明。
这里要理解的关键是ECMAScript语法不允许换行符分隔return
及其返回值表达式。它位于ES2015 §11.9.1, Rules of Automatic Semicolon Insertion:
ReturnStatement [Yield] :
return
[no LineTerminator 此处] 表达式;
return
[no LineTerminator 此处] 表达式 [In,?Yield];
ReturnStatement 在return
和表达式之间不能包含 LineTerminator 字符。
由于您做在return
和{ ... }
之间有换行符,因此{ ... }
部分不会被解析为属于return
}。它是独立的,这意味着它被解析为块。 { ... }
序列只有在作为较大语句或表达式的一部分时才能被解析为对象,例如
foo = { ... }
bar({ ... }
)return { ... }
)当{ ... }
纯粹单独在某一行上时,它被视为一个块。
由于第二种情况有一个块而不是一个对象,所以它不需要分号,如本答案开头所述。
答案 2 :(得分:0)
2件事,首先是
return {
hi: console.log("foo")
}
您需要;
来指定对象文字的结尾,此处
return
{
hi: console.log("foo1")
};
因为您没有在{
之后放置return
,而是;
它由js引擎(可选分号)放在那里。