前面一段时间,看到(function(){}),(function(){}())这些函数就犯晕,不知道它究竟是什么意思,为何函数外要加小括号,函数后要加小括号,加和不加到底有什么区别……一直犯迷糊,看了汤姆大叔的《深刻理解JavaScript系列(4):当即调用的函数表达式》后才明白它们究竟是什么东西,终于将困扰我已久的东西给干掉了。html
在这里,我先介绍一下函数引用和函数调用的差异、函数声明表现形式和函数表达式的表现形式。函数
1、函数引用和函数调用的差异htm
函数引用和调用的差异与函数名称后是否有小括号()有关,函数引用只会单独出现,但函数调用后面一定会带有一个小括号,不少时候还附有自变量。blog
表示方式(举例说明):ip
function foo(){ //函数体 } var f = foo; //函数引用 var ff = foo(); //函数调用,可直接调用foo(),也可调用f()
二、函数声明的表现形式作用域
带有函数名的函数是函数声明,包括保留字function,函数名(必有),圆括号中的参数(无关紧要)和花括号中的函数主体。get
表示方式(举例说明):it
function foo(str){ //函数体 }
3、函数表达式的表现形式io
赋值函数,函数外带有小括号的函数是函数表达式(就举两个例子),包括赋值变量(可有),函数外小括号(可有),保留字function,函数名(无关紧要),圆括号中的参数(无关紧要)和花括号中的函数主体。function
表示方式(举例说明):
//赋值型函数表达式 var f = function foo(str){ //函数体 } //分组括号型函数表达式,这是当即执行函数表达式,后面会讲解 (function(){ //函数体 })();
4、函数实例
第一种:
var foo = function(){}
分析:该函数为函数表达式,也能够理解成是一个引用,用foo()调用可执行。
第二种:
var foo = function(){}();
分析:该函数为当即调用函数,这和第一种的区别就是后面有无小括号,也就是函数调用和函数引用的区别,函数调用可理解为自执行函数(最好在function(){}外加一个括号变成(function(){})(),更规范一点);
第三种:
function(){}
分析:该函数缺乏名称,未赋值,因此报错。
第四种:
function(){}()
分析:function(){}是语句,不是函数表达式,只有表达式才能调用,因此报错。
第五种:
(function(){})();
分析:(function(){})是函数表达式,能调用,称为匿名自执行函数。
第六种:
(function(){}());
分析:(function(){}())是函数表达式,可用,称为匿名自执行函数(汤姆大叔推荐的写法,我更喜欢第五种写法)。
第七种:
function foo(){}
分析:该函数为实名函数,可调用。
第八种:
function foo(){}();
分析:解释和第四种同样,由于function foo(){}是语句,不是表达式,不能调用,因此报错。
第九种:
function foo(){}(a);
分析:解释和第四种同样,由于function foo(){}是语句,不是表达式,不能调用,可是由于后面括号中传入了参数,因此未抛出异常,也就为报错,可是自己仍是不执行的。
第十种:
(function foo(){});
分析:function外添加一个括号,因此外部做用域就不能调用foo()这个函数了,里面被当作匿名函数了,我我的认为这样的函数没什么意义,既不能调用也不能自执行。
第十一种:
(function foo(){})();
分析:有了十,这个就能够理解为是匿名自执行函数了。可是在ie8如下能执行,该表达式被当作函数声明,函数声明有种“置顶解析”的行为,就是无论函数在哪一个地方定义,它都会在该做用域顶部默认声明好。
第十二种:
!function(){}();
分析:其实小括号和js的&&,异或,逗号等操做是在函数声明和表达式消除歧义的,为可执行的。
第十三种:
new function(){}();
分析:可执行。
最后,很是感谢。有哪里讲解的很差或者是不正确的地方,但愿你们能第一时间反馈给我,但愿和你们共同进步~