转自:http://rensanning.iteye.com/blog/2080429
IIFE :immediately-invoked function expression 

(1)标准写法 
Js代码  收藏代码
  1. (function (window, document, undefined) {  
  2.   //   
  3. })(window, document);  


(2)作用域Scope 
JavaScript有function作用域,所以function首先创建一个私有的作用域,在执行的时候都会创建一个执行上下文。
Js代码  收藏代码
  1. (function (window, document, undefined) {  
  2.   var name = '张三';  
  3. })(window, document);  
  4. console.log(name); // 因为作用域不同,这里的name未定义。  


调用方法一: 
Js代码  收藏代码
  1. var logMyName = function (name) {  
  2.   console.log(name);  
  3. };  
  4. logMyName('李四');  


调用方法二: 
Js代码  收藏代码
  1. var logMyName = (function (name) {  
  2.   console.log(name);  
  3. })('王五');  


需要注意的是需要用括号把函数内容括起来: 
Js代码  收藏代码
  1. (function () {  
  2.   // ...  
  3. })();  


没有括号的话会报语法错: 
Js代码  收藏代码
  1. function () {  
  2.   // ...  
  3. }();  


也可以强制JavaScript识别代码(一般很少这么用): 
Js代码  收藏代码
  1. !function () {  
  2.   // ...  
  3. }();  
  4.   
  5. +function () {  
  6.   // ...  
  7. }();  
  8.   
  9. -function () {  
  10.   // ...  
  11. }();  
  12.   
  13. ~function () {  
  14.   // ...  
  15. }();  


比如: 
Js代码  收藏代码
  1. var a = !function () {  
  2.     return true;  
  3. }();  
  4. console.log(a); // 打印输出 false  
  5.   
  6. var b = (function () {  
  7.     return true;  
  8. })();  
  9. console.log(b); // 打印输出 true  


(3)参数Arguments 

传递参数给IIFE 
Js代码  收藏代码
  1. (function (window) {  
  2.   // 这里可以调用到window  
  3. })(window);  
  4.   
  5. (function (window, document) {  
  6.   // 这里可以调用到window和document  
  7. })(window, document);  


undefined参数 
在ECMAScript 3中undefined是mutable的,这意味着可以给undefined赋值,而在ECMASCript 5的strict模式('use strict';)下是不可以的,解析式时会报语法错。 

所以为了保护IIFE的变量需要undefined参数: 
Js代码  收藏代码
  1. (function (window, document, undefined) {  
  2.   // ...  
  3. })(window, document);  


即使有人给undefined赋值也没有关系: 
Js代码  收藏代码
  1. undefined = true;  
  2. (function (window, document, undefined) {  
  3.   // undefined指向的还是一个本地的undefined变量  
  4. })(window, document);  


(4)代码压缩Minifying 
Js代码  收藏代码
  1. (function (window, document, undefined) {  
  2.   console.log(window); // window对象  
  3. })(window, document);  
代码压缩后,undefined的参数不再存在,但是由于 (window, document); 的调用没有传递第三个参数,所有c依然是一个本地undefined变量,所有参数中undefined的名字是无所谓什么的,只需要知道他指向的是一个undefined变量。 
Js代码  收藏代码
  1. (function (a, b, c) {  
  2.   console.log(a); // window对象  
  3. })(window, document);  


除undefined变量外,其他的所有希望只在函数内部有效的变量都可以通过参数传递进去,比如以下的jQuery对象。 
Js代码  收藏代码
  1. (function ($, window, document, undefined) {  
  2.   // 使用 $ 指向 jQuery,比如:  
  3.   // $(document).addClass('test');  
  4. })(jQuery, window, document);  
  5.   
  6. (function (a, b, c, d) {  
  7.   // 代码会被压缩为:  
  8.   // a(c).addClass('test');  
  9. })(jQuery, window, document);  


本文转载:CSDN博客