并不是所有函数 都能够被立即执行,因此在写立即执行函数的时候,先要对语句,表达式,表达式语句,有一定的了解,鉴于这里面有点复杂,我这里只做简单说明,想要深刻理解,还是去查一下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模式的基本特征:
- 模块化,可重用
- 封装了变量和function,和全局的namaspace不接触,松耦合
- 只暴露可用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