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
~~~