? ? 很多時(shí)候我們?cè)趈s中定義一個(gè)函數(shù)后拌汇,只需要執(zhí)行該函數(shù)一次缚甩,比如數(shù)據(jù)初始化函數(shù)谱净;這種情況下,定義一個(gè)函數(shù)就會(huì)浪費(fèi)內(nèi)存空間擅威,這是我們可以使用立即執(zhí)行函數(shù)(Immediately-Invoked Function Expression 即IIFE)壕探。
函數(shù)調(diào)用
方式1:
? ? 定義一個(gè)函數(shù)后,我們可以通過(guò)()進(jìn)行調(diào)用郊丛,如下:
????????????function fn(){}
????????????fn();
? ? 那么我們是否可以通過(guò)如下的方式直接調(diào)用函數(shù)呢李请?
? ? ? ? ? ? function fn(){}();? ? ? //SyntaxError: Unexpected token )
? ? 結(jié)果是報(bào)語(yǔ)法錯(cuò)誤瞧筛,因?yàn)檎Z(yǔ)句是無(wú)法執(zhí)行的,所以js解析器在解析時(shí)捻艳,把該語(yǔ)句解析成了一個(gè)函數(shù)和一個(gè)分組操作符驾窟,如下:
? ? ? ? ? ? function fn(){}
? ? ? ? ? ? ();
? ? 而分組操作符內(nèi)不能為空,所以報(bào)了語(yǔ)法錯(cuò)誤认轨。
?方式2:
? ? 另一個(gè)在函數(shù)定義和調(diào)用的方式如下:
? ? ? ? ? ? var fn = function(){};
? ? ? ? ? ? fn();
? ? 可以看出绅络,匿名函數(shù)賦值給一個(gè)變量后,也可以作為函數(shù)被調(diào)用嘁字,那么是否可以通過(guò)如下方式直接調(diào)用函數(shù)呢恩急?
? ? ? ? ? ? function(){}();? ? ? //SyntaxError: Unexpected token (
? ? 結(jié)果依然是報(bào)語(yǔ)法錯(cuò)誤,原因是js解析時(shí)纪蜒,除非顯示的將函數(shù)定義為表達(dá)式衷恭,否則解析器都會(huì)將其當(dāng)做函數(shù)申明,而上面的語(yǔ)句就是將其當(dāng)做了函數(shù)申明纯续,而函數(shù)聲明必須要有函數(shù)名随珠,故解析都( 括號(hào)后報(bào)錯(cuò)。
實(shí)現(xiàn)立即調(diào)用
? ? 通過(guò)上面的分析可以看出猬错,一個(gè)函數(shù)如果想要立即執(zhí)行窗看,那么就必須顯示的將函數(shù)定義為表達(dá)式的形式。故可以通過(guò)如下的一些方式倦炒,定義一個(gè)立即執(zhí)行函數(shù):
? ? 1. (function(){}())? //最推薦的方式显沈,外面的括號(hào)將內(nèi)部的函數(shù)顯示的定義為函數(shù)表達(dá)式
? ? 2. (function(){})()? ? //完全等同于以上的方式
? ? 3. !function(){}();? // 通過(guò)!元素符將函數(shù)顯示的定義為表達(dá)式逢唤,然后執(zhí)行拉讯,同理:+,- 也可以
? ? 4. var fn = function(){}();? //通過(guò)賦值運(yùn)算符將函數(shù)顯示的定義為表達(dá)式鳖藕,然后執(zhí)行
總之魔慷,實(shí)現(xiàn)函數(shù)立即執(zhí)行的方式很多,但有的會(huì)與函數(shù)的返回值進(jìn)行運(yùn)行吊奢,如:盖彭!,+页滚,- ;為了避免這種麻煩铺呵,我們通常采用1和2兩種方式定義裹驰。
作用
? ? 立即執(zhí)行函數(shù)的作用:
? ? ? ? 1. 解決閉包中的狀態(tài)保存問(wèn)題;(常見(jiàn)的一個(gè)函數(shù)內(nèi)部返回多個(gè)函數(shù)片挂,調(diào)用這些函數(shù)幻林,打印父函數(shù)內(nèi)部變量的問(wèn)題)
? ? ? ? 2. 模塊化開(kāi)發(fā)中贞盯,定義私有變量,防止污染全局沪饺;
? ? ? ? 3. 初始化數(shù)據(jù)和頁(yè)面
注意:函數(shù)表達(dá)式定義的函數(shù)躏敢,函數(shù)名外部無(wú)法引用,如下:
? 1.? var fn = function f(){};
? ??? console.log(typeof f);??//打印undefined整葡,函數(shù)表達(dá)式的函數(shù)名f在外部是訪問(wèn)不到的
? ?2. if(function f(){}){
? ? ? ? ? ? console.log(typeof f);? //同理件余,打印undefined,if語(yǔ)句中的函數(shù)解析為函數(shù)表達(dá)式遭居,函數(shù)名f在外部是訪問(wèn)不到的
????????}
? ??