并不是所有函数 都能够被立即执行,因此在写立即执行函数的时候,先要对语句,表达式,表达式语句,有一定的了解,鉴于这里面有点复杂,我这里只做简单说明,想要深刻理解,还是去查一下javascript指南。

在JavaScript中,等于号=和分号;之间的代码就是条件表达式,使用分号可以连接两个语句,

表达式:(一个表达式会产生一个值)又可以看作是一个执行语句(因为它能执行某些功能,比如执行一个函数等)

javascript中有三种函数类型:函数声明,函数表达式和函数构造器创建的函数。

(1)函数声明(FD)function foo(){ statements; }

(2)函数表达式(FE)   var foo = function(){ statements;}

(3)函数构造器创建    var foo = new Function(expressions);

函数表达式是能够被立即执行的

 

对于一个表达式语句,当你无法区分它是表达式还是语句,你参照上下文,判断程序在这需要做什么,是变量赋值?还是语句执行?看到前面由“=”(赋值)或者用“()”(小括号,在这时分组符,里面只能包含表达式),你就可以肯定,这是一个表达式上下文。javascript的解释器就是这个干的。

因此函数表达式是可以被我们强制转换的

(1)利用小括号,也就是分组符号(分组符内只允许表达式),进行转换。

JavaScript里括弧()里面不能包含语句,所以在这一点上,解析器在解析function关键字的时候,会将相应的代码解析成function表达式,而不是function声明。

(function () { /* code */ } ()); // 推荐使用这个

(function(){alert(1);})();  // 但是这个也是可以用

 

(2)利用运算符,因为javascript引擎会认为这是参与运算的必须是表达式。

// 由于括弧()和JS的&&,异或,逗号等操作符是在函数表达式和函数声明上消除歧义的

// 所以一旦解析器知道其中一个已经是表达式了,其它的也都默认为表达式了

 

var i = function () { return 10; } (); //根据上下文判断,"var i = "后面是表达式上下文,所有解释器自动将后面看成一个立即执行函数,虽然没有小括号。

true && function () { /* code */ } ();

0, function () { /* code */ } ();

 

!function () { /* code */ } ();

~function () { /* code */ } ();

-function () { /* code */ } ();

+function () { /* code */ } ();

// 还有一个情况,使用new关键字,也可以用,

new function () { /* code */ } ()

// 如果需要传递参数,只需要加上括弧()

 

在这穿插一下,之前做项目 总是遇到ajax返回数据用eval(),里面写2个()的原因,当时不明白,都是前人怎么写,我也跟着写,在看立即执行函数资料的的时候找到了原因;

var o;

o = eval("{obj:'this is a object'}")
console.log(o); //this is a object

o = eval("({obj:'this is a object'})")
console.log(o); //Object {obj: "this is a object"}

前者eval中没有加小括号,运行时被认为是一条语句执行,所以o被赋值成字符串了;而后者,被认为是加上小括号,被认为是在表达式上下文中执行,所以返回一个对象。

 

以下是本文重点,在理解了以上信息之后,我们要写一个在项目中经常用到模块写法

Module模式的基本特征:

  1. 模块化,可重用
  2. 封装了变量和function,和全局的namaspace不接触,松耦合
  3. 只暴露可用public的方法,其它私有方法全部隐藏

 

(function ($, YAHOO) {
// 这里,我们的代码就可以使用全局的jQuery对象了,YAHOO也是一样
} (jQuery, YAHOO));

现在很多类库里都有这种使用方式,比如jQuery源码。
不过,有时候可能不仅仅要使用全局变量,而是也想声明全局变量,如何做呢?我们可以通过匿名函数的返回值来返回这个全局变量,这也就是一个基本的Module模式,来看一个完整的代码:
var blogModule = (function () {
var my = {}, privateName = "博客园";

function privateAddTopic(data) {
// 这里是内部处理代码
}

my.Name = privateName;
my.AddTopic = function (data) {
privateAddTopic(data);
};

return my;
} ());


还有其他高级属性,鉴于自己还没接触到,等以后接触到了,在总结吧!

以上总结都是个人理解,欢迎大家批评指正

 参考文章:http://www.cnblogs.com/TomXu/archive/2011/12/30/2288372.html