JavaScript中两个模块的声明有什么区别?

JavaScript中两个模块的声明有什么区别? 一个在function上有括号,另一个没有?

一篇文章说

注意()周围的匿名函数。 这是语言所要求的,因为以token函数开头的语句总是被认为是函数声明。 包括()将创build一个函数expression式。

两者似乎都做同样的事情时,检查。

var person = (function () { // Private var name = "Robert"; return { getName: function() { return name; }, setName: function(newName) { name = newName; } }; }()); 

 var person = function () { // Private var name = "Robert"; return { getName: function() { return name; }, setName: function(newName) { name = newName; } }; }(); 

函数在JavaScript中有两种types – 声明和expression式。

这是两者之间的区别:

  1. 函数声明被挂起。 这意味着你可以在程序出现之前调用该函数,因为在JavaScript中声明被挂起
  2. 函数expression式可以立即调用。 函数声明不能​​。 这是因为expression式expression (或返回一个值)。 函数expression式表示一个函数。

函数声明的一个例子:

 foo("bar"); function foo(bar) { alert("foo" + bar); } 

上面的程序将工作,因为foo是一个函数声明。

 foo("bar"); // throws an error, foo is undefined - not a function var foo = function (bar) { alert("foo" + bar); }; 

上面的程序将不起作用,因为foo被声明为undefined ,被吊起来,然后赋值函数expression式的值。 因此,它被称为是undefined的。

函数expression式的一个例子:

 (function (bar) { alert("foo" + bar); }("bar")); 

上面的函数将被立即调用,因为它是一个函数expression式。

 function (bar) { alert("foo" + bar); }("bar"); // throws an error, can't call undefined 

上面的函数不会被立即调用,因为它是一个函数声明。 请记住,声明不表示(或返回值)。 所以这就像试图调用undefined的函数。

函数如何成为一个expression式?

如果在需要expression式的上下文中使用函数,则将其视为expression式。 否则,它被视为一个声明。

预计expression时:

  1. 你正在给一个variables赋值(即identifier = expression )。
  2. 括号内(即( expression ) )。
  3. 作为运算符的操作数(即operator expression )。

因此下面是所有的函数expression式:

 var foo = function () {}; (function () {}); ~function () {}; 

其他的一切都是一个函数声明。 总之,如果你的function没有任何东西,这是一个声明。

看到这个代码: https : //github.com/aaditmshah/codemirror-repl/blob/master/scripts/index.js#L94

下面的函数isExpression用来testing一些任意的JavaScript代码是否是一个expression式:

 function isExpression(code) { if (/^\s*function\s/.test(code)) return false; try { Function("return " + code); return true; } catch (error) { return false; } } 

希望这可以消除你心中的疑虑。

简而言之:

  1. 函数expression式expression或返回一个值(在这个例子中是一个函数)。 因此可以立即调用,但在程序出现之前不能被调用。
  2. 函数声明被挂起 。 因此可以在程序出现之前调用它。 但是,由于它没有expression任何价值,所以不能立即调用。

在目前的情况下,翻译没有任何区别。 通常最好的写模块的方式是用圆括号包装函数:

 var person = (function () { // Private var name = "Robert"; return { getName : function () { return name; } }; }()); 

这是因为语法更清晰,显然你想在声明后立即调用函数。 还有一个原因是因为:

 (function () { //some stuff }()); 

将工作,但

 function () { //some stuff }(); 

这不会。

每次使用通常的编码风格时,通过包装函数通常是件好事:-)。

不同之处在于写作时:

 var foo = (function () { ... }()); 

使用(多余的但有用的)分组()是一种常见的编码风格,从非常类似的第一行中清楚地知道右手边很可能是立即调用的函数expression式(IIFE)。 但是,在第二个:

 var foo = function () { ... }(); 

直到你阅读最后一行,这可能是相当多的几行。 在你到达最后一行之前,你可能以为你正在阅读一个简单的任务:

 var foo = function () { ... }; 

请注意,圆括号也可用于明文分配中:

 var foo = (function () { ... }); 

但在这种情况下,他们确实是多余的(并且可能因为将它们用于IIFE而被误导)。

见一对重要的父母 。