完整代码:
function foo1(){ return {msg: "hello1"}; } function foo2(){ return {msg: "hello2"}; } // output = "foo1 = {"msg":"hello1"}" console.log('foo1 = ' , JSON.stringify(foo1())); //output = " foo2 = undefined " console.log('foo2 = ' , JSON.stringify(foo2()));
两者之间的区别在于,在foo2中,the {msg: 'hello'}位于其自己的新行中。我期望解析器忽略空格?
{msg: 'hello'}
tl; dr 换行引起第二个函数的“未定义”。JavaScript在很多情况下不需要分号,而只是在某些情况下假定它们自动分号插入。
在某些情况下,为避免此ASI问题并出于美学原因,我使用了所谓的分组运算符。例如,使用hoquet模板DSL(它将Array作为s表达式编译为HTML),我喜欢对Array进行分组,以便它们清楚地显示HTML结构:
return ( ["ul" , ["li" , ["span", {class: "name"}, this.name] , ["span", {id: "x"}, "x"] ] ] );
对于我来说,这似乎更清晰或更一致
return [ "ul", [ "li", ["span", {class: "name"}, this.name], ["span", {id: "x"}, "x"] ] ];
它们最终以相同的行数结束。但这确实是美学问题。
分组运算符只计算其中的任何表达式。在“立即调用函数表达式”中通常会看到这种情况,您需要将通常是函数声明的内容转换为表达式,然后可以立即调用该表达式(因此称为名称)。但是,分组运算符的一个鲜为人知的特征是它也可以采用逗号分隔的表达式列表,例如
function() { return ( doSideEffects(), console.log("this is the second side effect"), 1 + 1 ); }
在这种情况下,它将计算这些表达式中的每一个,并仅返回最后一个(1 + 1)。