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式。
这是两者之间的区别:
- 函数声明被挂起。 这意味着你可以在程序出现之前调用该函数,因为在JavaScript中声明被挂起 。
- 函数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时:
- 你正在给一个variables赋值(即
identifier = expression
)。 - 括号内(即
( expression )
)。 - 作为运算符的操作数(即
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; } }
希望这可以消除你心中的疑虑。
简而言之:
- 函数expression式expression或返回一个值(在这个例子中是一个函数)。 因此可以立即调用,但在程序出现之前不能被调用。
- 函数声明被挂起 。 因此可以在程序出现之前调用它。 但是,由于它没有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而被误导)。
见一对重要的父母 。