您能解释JavaScript中封装的匿名函数的语法背后的原因吗?为什么起作用:(function(){})();但这不起作用function(){}();?
(function(){})();
function(){}();
在JavaScript中,将创建一个命名函数,如下所示:
function twoPlusTwo(){ alert(2 + 2); } twoPlusTwo();
您还可以创建一个匿名函数并将其分配给变量:
var twoPlusTwo = function(){ alert(2 + 2); }; twoPlusTwo();
您可以通过创建一个匿名函数来封装代码块,然后将其包装在方括号中并立即执行:
(function(){ alert(2 + 2); })();
在创建模块化脚本时,这很有用,以避免因潜在冲突的变量而使当前范围或全局范围混乱(例如Greasemonkey脚本,jQuery插件等)。
现在,我明白了为什么这样做了。方括号将内容括起来,仅显示结果(我敢肯定有一种更好的描述方式),例如with (2 + 2) === 4。
(2 + 2) === 4
但是我不明白为什么这不能同样有效:
function(){ alert(2 + 2); }();
你能跟我解释一下吗?
它不起作用,因为它被解析为a FunctionDeclaration ,并且函数声明的名称标识符是 强制性的 。
FunctionDeclaration
当用括号将其括起来时,它将被评估为 FunctionExpression ,并且可以命名或不命名函数表达式。
FunctionExpression
a的语法FunctionDeclaration如下:
function Identifier ( FormalParameterListopt ) { FunctionBody }
和FunctionExpressions:
function Identifieropt ( FormalParameterListopt ) { FunctionBody }
如您所见,Identifier(Identifieropt)令牌FunctionExpression是可选的,因此我们可以使用没有定义名称的函数表达式:
Identifier
(function () { alert(2 + 2); }());
或 命名 函数表达式:
(function foo() { alert(2 + 2); }());
括号(正式称为[分组运算符)只能包围表达式,并且会评估函数表达式。
这两个语法产生可能会模棱两可,并且看起来可能完全相同,例如:
function foo () {} // FunctionDeclaration 0,function foo () {} // FunctionExpression
解析器根据它出现的 上下文* 知道它是a FunctionDeclaration还是a 。FunctionExpression *
在上面的示例中,第二个是表达式,因为逗号运算符也只能处理表达式。
另一方面,FunctionDeclarations实际上只能出现在所谓的“ Program”代码中,这意味着代码在全局范围之外以及在FunctionBody其他函数的内部。
Program
FunctionBody
应该避免在块内部使用函数,因为它们会导致不可预测的行为,例如:
if (true) { function foo() { alert('true'); } } else { function foo() { alert('false!'); } } foo(); // true? false? why?
上面的代码实际上应该产生一个SyntaxError,因为aBlock只能包含语句(并且ECMAScript规范没有定义任何函数语句),但是大多数实现是可以容忍的,并且将仅采用第二个函数,即alert的第二个函数'false!'。
SyntaxError
Block
'false!'
Mozilla实现-Rhino,SpiderMonkey-具有不同的行为。它们的语法包含一个非标准Function语句,这意味着该函数将在 运行时而 不是在解析时进行评估,因为它会与FunctionDeclarations一起发生。在这些实现中,我们将定义第一个函数。
可以用不同的方式声明函数,请比较以下内容:
1-一个函数,该函数使用分配给变量的Function构造函数 乘法 :
var multiply = new Function("x", "y", "return x * y;");
2-名为 乘法 的函数的函数声明:
function multiply(x, y) { return x * y; }
3-分配给变量 multipli的 函数表达式:
var multiply = function (x, y) { return x * y; };
4-命名函数表达式 func_name ,分配给变量 multipli :
var multiply = function func_name(x, y) { return x * y; };