最近在写代码时遇到了闭包,其中闭包又和立即执行函数(immediately invoked function expression, aka IIFE)有点关系,于是牵扯除了函数声明以及函数表达式,我感觉中文的很多文章写的不太好,查阅了和,觉得写的很好,整合一下。
Firstly, in JS there are two ways of defining functions: function declarations and function expressions, aka 函数声明和函数表达式。
- function declaration (function definition or function statement)
This is always followed by the name of the function (which is very important cauz function declaration requires a name, if not, it may encounter some SyntaxError, we can see from the following examples), a list of parameters and the JavaScript statements that define the function, enclosed in curly braces{}.
- function expression
This can be anonymous; it doesn't have to have a name;
var ab = function(){}; //anonymous function expressionvar ac = function ad() {};// function expression with a name
.
.SyntaxError will happen in the following case when lack of a name:var foo = function(){}; //this is a anonymous function expression we will see in the futurefoo(); //we can invoke the function by adding parens after foo// then some people might think of the following, since foo equals to function(){} and foo() can be used, why don't we use function{}()?function(){}(); // However, there will be a SyntaxError: "unexpected ("
1.1 What leads to this SyntaxError?
The reason is that the parser treats it as a function declaration without a name rather than a function expression. Now that, what about we give it a name by usingfunction foo(){}();// there will also be a SyntaxError: "unexpected )"
1.2 What leads to the other SyntaxError?
This is because parens placed after the stataments are view as a grouping operator which needs to contain an expression;OK, here I finally got the idea and there must be no error! Why don't we use this:function foo(){}(1); //no error
1.3 In this case, however, the function is not executed either despite there is no error. Here is the reason, the parser treated this as two separate unrelated expression
function foo(){}; (1);
.
.Is there any way to solve the problem????Yep! The solution is IIFE(立即执行函数)!!!!!!(function(){})();(function(){}());
Unlike in 1.1, the parser encounters function keyword and knows that now I need to treat it like function expression rather than a function declaration! Such parens indicate that the function expression will be immediately invoked and the variable will contain the result of the function.
也就是说,只要不让function这个关键词出现在行首就行,所以下面的情况都可以。~function(){}();!function(){}();
One application of IIFE -- Closure(闭包)
IIFE is used to lockin values and effectively save state.
The advantage is that since the function is invoked immediately without an identifier, a closure can be used without polluting the current scope.