以下JavaScript闭包函数的外部额外括号的用途是什么?在其他帖子中我被告知它们并不是绝对必要的,但是它们是一个约定,以明确函数的结果被传递,而不是函数本身。来自http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html的以下引用 然而,冲突。哪个是对的?
注意匿名函数周围的()。这是必需的 语言,因为以令牌函数开头的语句是 始终被认为是函数声明。包括()创建一个 而是函数表达式。
(function () {
// ... all vars and functions are in this scope only
// still maintains access to all globals
}());
答案 0 :(得分:6)
我认为不同的引擎有不同的解释方式
function(){...}();
因此,对所有引擎来说,最流行和最常用的方法是将代码分组到括号中。
(function(){...}());
与此同时,你引用的内容非常有趣。函数表达式可能会出现:
var f = function() {...}
虽然函数声明如下:
function f() {...}
你看到解析器如何通过查看第一个令牌来轻松/方便地区分它?
IF TOKEN1 EQ "function": FXN DECLARATION
ELSE: FXN EXPRESSION
但是你的(立即调用的)函数是一个函数声明是没有意义的(它不会被重用,你不想让它被提升,或者在命名空间中等等。因此,添加一些无关紧要的括号是指示它是函数表达式的好方法。
答案 1 :(得分:5)
首先,我必须清理:
(function () {
}());
等同于
(function () {
})();
以及(Backbone.js使用它)
(function(){
}).call(this);
其次,如果您打算以这种方式使用它,那么它不是匿名/闭包函数。其立即调用的函数表达式
如果将返回的上下文分配给变量,它将充当闭包(因为它不会立即被调用)。如果你需要一个静态类(当没有实例化时可以访问属性和方法),这种方法很有用。例如:
var stuff = (function(){
// AGAIN: its not an IIFE in this case
function foo() // <- public method
{
alert('Jeeez');
}
return {
foo : foo,
}
})();
stuff.foo(); //Alerts Jeeez
下面的外部额外括号的目的是什么? JavaScript闭包函数?
目的不常见而且非常奇怪 - 它都是关于函数参数的。 例如,
(function(window, document){ // <- you see this? 2 "arguments"
alert(arguments.length); // 0!
})();
但如果我们将它们传递给那个外部括号
(function(/* So its not for arguments */ ){
alert(arguments.length); // 2
})(window, document); // <- Instead we pass arguments here
答案 2 :(得分:4)
额外的周围括号消除了常规函数声明中的函数表达式。
虽然额外的括号是标准做法,但通过这样做可以实现同样的目的:
void function() {
// do stuff
}();
或者,甚至:
+function() {
// do stuff
}();
尽管在这两种选择中,我更喜欢void
符号,因为在大多数情况下,我们并不关心立即调用的返回值。
不需要括号的其他地方是预期表达式时:
setTimeout(function() {
return function() {
alert('hello');
}
}(), 1000);
答案 3 :(得分:1)
它们是必需的,因为解析器在看到
时进入函数声明模式function
在语句上下文中。
在function
标记之后,它期望该函数的名称,因为函数声明必须包含该函数的名称。但它代替了(
而不是名称,所以这是一个语法错误。
我认为,它可以回溯并且毫不含糊地将其视为函数表达式,但事实并非如此。
<小时/>
var module = XXX
在上文中,XXX
位于表达式上下文中,如果出现function
,则将其视为函数表达式的开头。函数表达式不必具有
函数的名称,因此(
之后function
出现var module = function(){}();
不是语法错误。
所以你可以写:
function(){}()
但不是
(XXX)
!XXX
~XXX
+XXX
//This doesn't work however:
{YYY} //the braces are delimiting a block, and inside block you start in
//a statement context
您可以使用许多技巧使上面的表达式成为:
XXX
XXX
在表达式上下文中,因为它用括号括起来或跟在一元运算符之后,因此替换{{1}}的任何函数都是函数表达式。