? ? 很多時候我們在js中定義一個函數后,只需要執行該函數一次,比如數據初始化函數;這種情況下,定義一個函數就會浪費內存空間,這是我們可以使用立即執行函數(Immediately-Invoked Function Expression 即IIFE)。
函數調用
方式1:
? ? 定義一個函數后,我們可以通過()進行調用,如下:
????????????function fn(){}
????????????fn();
? ? 那么我們是否可以通過如下的方式直接調用函數呢?
? ? ? ? ? ? function fn(){}();? ? ? //SyntaxError: Unexpected token )
? ? 結果是報語法錯誤,因為語句是無法執行的,所以js解析器在解析時,把該語句解析成了一個函數和一個分組操作符,如下:
? ? ? ? ? ? function fn(){}
? ? ? ? ? ? ();
? ? 而分組操作符內不能為空,所以報了語法錯誤。
?方式2:
? ? 另一個在函數定義和調用的方式如下:
? ? ? ? ? ? var fn = function(){};
? ? ? ? ? ? fn();
? ? 可以看出,匿名函數賦值給一個變量后,也可以作為函數被調用,那么是否可以通過如下方式直接調用函數呢?
? ? ? ? ? ? function(){}();? ? ? //SyntaxError: Unexpected token (
? ? 結果依然是報語法錯誤,原因是js解析時,除非顯示的將函數定義為表達式,否則解析器都會將其當做函數申明,而上面的語句就是將其當做了函數申明,而函數聲明必須要有函數名,故解析都( 括號后報錯。
實現立即調用
? ? 通過上面的分析可以看出,一個函數如果想要立即執行,那么就必須顯示的將函數定義為表達式的形式。故可以通過如下的一些方式,定義一個立即執行函數:
? ? 1. (function(){}())? //最推薦的方式,外面的括號將內部的函數顯示的定義為函數表達式
? ? 2. (function(){})()? ? //完全等同于以上的方式
? ? 3. !function(){}();? // 通過!元素符將函數顯示的定義為表達式,然后執行,同理:+,- 也可以
? ? 4. var fn = function(){}();? //通過賦值運算符將函數顯示的定義為表達式,然后執行
總之,實現函數立即執行的方式很多,但有的會與函數的返回值進行運行,如:!,+,- ;為了避免這種麻煩,我們通常采用1和2兩種方式定義。
作用
? ? 立即執行函數的作用:
? ? ? ? 1. 解決閉包中的狀態保存問題;(常見的一個函數內部返回多個函數,調用這些函數,打印父函數內部變量的問題)
? ? ? ? 2. 模塊化開發中,定義私有變量,防止污染全局;
? ? ? ? 3. 初始化數據和頁面
注意:函數表達式定義的函數,函數名外部無法引用,如下:
? 1.? var fn = function f(){};
? ??? console.log(typeof f);??//打印undefined,函數表達式的函數名f在外部是訪問不到的
? ?2. if(function f(){}){
? ? ? ? ? ? console.log(typeof f);? //同理,打印undefined,if語句中的函數解析為函數表達式,函數名f在外部是訪問不到的
????????}
? ??