JavaScript闭包之自执行函数和匿名函数
最近重学了一遍JavaScript关于闭包这一块的知识,收益颇多。所以想花点时间进行一个总结,接下来的几篇文章都会讲解关于闭包这一块的知识,闭包也是JavaScript中一大难点,牵扯到的知识点太多,今天就让我先来说说自执行函数和匿名函数吧。
什么是函数?
函数时JavaScript中最灵活也是最容易让人困惑的对象。定义函数方式有两种:
- 函数声明
1 | function functionName(arg0, arg2, arg3) { |
- 函数表达式
1 | var functionName = function(arg0, arg1, ard2) { |
这里只是简单介绍下,想了解很多请参考《JavaScript高级程序设计》
自执行函数(IIFE)
IIFE( 立即调用函数表达式)是一个在定义时就会立即执行的 JavaScript 函数。 –MDN
类似于下面的代码,就是一个自执行函数
1 | (function(i, undefined){ |
第一眼看过去,怎么跟我们上面说的不一样啊,函数定义的方式不是只有函数声明和函数表达式吗?这是什么操作,写错了吧!别急,听我慢慢道来。
相信看过一些库的源码的小伙伴一定见过这种写法
1 | ~function(){ |
或者这种方式
1 | +function(){ |
其实这些写法的作用都一样,都是把function()转化成一个可执行的表达式,方便执行。其实我们可以这样看
1 | var fn = function(i, undefined){ |
这样看是不是好理解多了,这不就是我们上面说的函数表达式定义函数嘛,只不过在这儿是让这个函数马上执行了而已。
但是如果我们这么写
这个时候,小伙伴们是不是心中就有个疑问了,为什么(function {// code})();可以被执行, 而function {// code}();却会报错?
- 首先我们要清楚,(function {// code})()是函数表达式,而function {// code}();是函数声明。
- js存在预编译的过程,在预编译的时候,会解释函数声明,而忽略函数表达式。
- 当js执行到function() {//code}();时, 由于function() {//code}在”预编译”阶段已经被解释过, js会跳过function(){//code}, 试图去执行();, 故会报错;
当js执行到(function {// code})();时, 由于(function {// code})是表达式, js会去对它求解得到返回值, 由于返回值是一个函数, 故而遇到();时, 便会被执行。
所以这个报错是在函数执行时才报错的,而不是在预编译阶段。
理解了第一个括号的意思,第二个括号的意思就简单多了,就是函数的执行表达式。
关于更多自执行函数的内容,可以参考Javascript模块化编程(一):模块的写法。
匿名函数
顾名思义,匿名函数就是没有函数名的函数。
上面说到,JavaScript定义函数的两种方式利用函数声明和函数表达式,而匿名函数就是通过函数表达式创建的。
1 | setTimeout( |
上面的例子中函数并没有函数名,所以它就是一个匿名函数。
再来看看我们刚才的自执行函数
1 | (function(i, undefined){ |
没错,这是一个自执行的匿名函数。
匿名函数的使用最主要就是方便,毕竟在很多情况下函数的名字并不那么重要。大多数情况下匿名函数和有名函数都可以很好地完成多数任务。
匿名函数还有一个最大的用途就是用来创建闭包,这个我们放在后面再说。
本文完