IIFE(Imdiately Invoked Function Expression 立即执行的函数表达式)
* * * * *
下面的这段代码放在console中执行,会报错
~~~
function(){
alert('IIFE');
}
~~~
因为这个是一个匿名函数,要想让它正常运行就必须给个函数名,然后通过函数名调用。
而我们看到很多类库写的时候也是匿名函数结果不报错,那是因为这些函数的前面加了符号之后,就把一个函数声明语句变成了一个函数表达式,是表达式就会在script标签中自动执行。
#### 运算符
①为什么加上了这些运算符后就能让一个匿名函数变成一个不会报错的函数表达式呢?
我们自然会想到javascript的解析器到底是怎么工作识别的呢,js解析器执行js表达式这个肯定是没有问题的。其实无论是括号,还是感叹号,让整个语句合法做的事情只有一件,就是让一个函数声明语句变成了一个表达式。所以我们让一个函数定义变成一个函数表达式来执行就不会报错。
②原理
这样是一个函数声明
~~~
function a(){
alert('IIFE');
}
~~~
这样是一个函数调用
~~~
a();
~~~
理解一下就是在一个声明了的函数后面如果加上一个()就可以调用函数。
但是我们按下面的调用方法在console中执行却发现出错了
~~~
function a(){
alert('IIFE');
}()
~~~
因为这样的代码混淆了函数声明和函数调用,以这种方式声明的函数 a,就应该以 a(); 的方式调用。
但是括号则不同,它将一个函数声明转化成了一个表达式,解析器不再以函数声明的方式处理函数a,而是作为一个函数表达式处理,也因此只有在程序执行到函数a时它才能被访问。所以,任何消除函数声明和函数表达式间歧义的方法,都可以被解析器正确识别。所以,赋值,逻辑,甚至是逗号,各种操作符都可以告诉解析器,这个不是函数声明,它是个函数表达式。并且,对函数一元运算可以算的上是消除歧义最快的方式,感叹号只是其中之一,如果不在乎返回值,这些一元运算都是有效的:
~~~
!function(){alert('iifksp')}() // true
+function(){alert('iifksp')}() // NaN
-function(){alert('iifksp')}() // NaN
~function(){alert('iifksp')}() // -1
~~~