匿名函數(shù)自執(zhí)行,顧名思義,指的是不需要定義函數(shù)名就可以直接執(zhí)行的函數(shù)。這種函數(shù)有時(shí)也被稱作“立即執(zhí)行函數(shù)”(Immediately Invoked Function Expression,IIFE)。Javascript匿名函數(shù)自執(zhí)行的特點(diǎn)在于,函數(shù)聲明之后立即執(zhí)行一次,執(zhí)行結(jié)果一般會(huì)返回一個(gè)值,可以將這個(gè)值賦給變量或者對(duì)象屬性等。下面我們通過舉例來更加深入地了解匿名函數(shù)自執(zhí)行。
首先,我們看一個(gè)最基本的IIFE,它的寫法如下:
(function() { console.log("Hello world!"); })();這個(gè)函數(shù)聲明同時(shí)就被執(zhí)行,并輸出了“Hello world!”。注意到最后的兩個(gè)括號(hào)是整個(gè)函數(shù)的調(diào)用符號(hào)。這段代碼等價(jià)于這種寫法:
var fn = (function() { console.log("Hello world!"); }); fn();但是,因?yàn)榈谝粋€(gè)寫法直接執(zhí)行了函數(shù),所以我們并不需要給這個(gè)函數(shù)命名,也不需要再單獨(dú)地執(zhí)行fn()。這種方法可以比第二種方式更方便地使用,也更加容易管理。 接下來,我們來看看如何將變量、參數(shù)等傳遞給IIFE。我們可以向IIFE傳遞變量的值、函數(shù)所需的其他參數(shù)等。使用這種方式,我們可以將IIFE作為其他函數(shù)的一部分來使用,而不需要再定義其他函數(shù)。
(function(x) { console.log(x); })("Hello world!");這個(gè)例子輸出了“Hello world!”。我們把字符串值傳遞給了IIFE,并且打印出了這個(gè)值。這是一種非常簡(jiǎn)單的變量傳遞方法,它可以方便地應(yīng)用于許多場(chǎng)景。 我們還可以在自執(zhí)行函數(shù)中定義和使用私有變量(或函數(shù)):
(function() { var x = 1; function privateFunction() { console.log("This is a private function, x = " + x); } return { publicFunction: function() { console.log("This is a public function, x = " + x); privateFunction(); } }; })().publicFunction();這段代碼定義了一個(gè)IIFE,其中包含一個(gè)名為“privateFunction”的私有函數(shù)和一個(gè)名為“publicFunction”的公共函數(shù)。IIFE返回一個(gè)包含公共函數(shù)的對(duì)象,公共函數(shù)輸出了x的值,并且調(diào)用了私有函數(shù),打印了x的值。在IIFE內(nèi)部定義的變量會(huì)被封裝,對(duì)于外部代碼是不可見的,這些變量只能在IIFE內(nèi)部訪問。這種技巧可以用來實(shí)現(xiàn)模塊化設(shè)計(jì)和防止變量污染等需求。 另外,我們可以利用IIFE的函數(shù)作用域特點(diǎn)來編寫一些耐用、易于測(cè)試的代碼。下面看一個(gè)例子:
(function(window) { function protectedFunction() { console.log("This is a protected function."); } window.myObj = { publicFunction: function() { console.log("This is a public function."); }, callProtectedFunction: function() { protectedFunction(); } }; })(window); myObj.publicFunction(); myObj.callProtectedFunction();這個(gè)例子中,首先我們傳遞了window對(duì)象,然后定義了一個(gè)私有的protectedFunction()函數(shù)。接著,我們返回包含兩個(gè)公共函數(shù)的對(duì)象,外界代碼可以直接通過myObj來調(diào)用這兩個(gè)函數(shù)。最后,我們使用myObj來測(cè)試這兩個(gè)公共函數(shù),然而,protectedFunction()函數(shù)卻無法對(duì)外使用,也無法在外部代碼中直接訪問。這樣的代碼可以大大減少外部與內(nèi)部代碼的耦合,并且更加易于測(cè)試。 對(duì)于IIFE的應(yīng)用場(chǎng)景,我們可以簡(jiǎn)單羅列出以下幾種: 1. 模塊化設(shè)計(jì):可以使用IIFE來創(chuàng)建閉包、定義私有變量、提供公共函數(shù)等,從而實(shí)現(xiàn)更加靈活、易于管理的模塊化代碼。 2. 防止變量污染:IIFE的函數(shù)作用域使得內(nèi)部變量和外部變量相互不影響,可以有效防止因?yàn)樽兞棵麤_突、重復(fù)定義而引起的問題。 3. 代碼性能優(yōu)化:IIFE可以避免不必要的變量定義、重復(fù)調(diào)用等問題,從而提升代碼執(zhí)行效率。 4. 封裝常用代碼:IIFE可以將常用的代碼(比如JSON序列化和反序列化、自定義事件、DOM操作等)封裝成一個(gè)對(duì)象,并導(dǎo)出公共函數(shù)供外部使用,這樣可以簡(jiǎn)化代碼、方便開發(fā),同時(shí)使代碼更加高效。 總之,IIFE是一種非常實(shí)用的javascript特點(diǎn),它可以幫助我們實(shí)現(xiàn)更加高效、靈活和易于管理的代碼結(jié)構(gòu)。盡管它在語法上有些獨(dú)特,但是只要掌握了IIFE的使用方法,就可以在實(shí)際開發(fā)中充分發(fā)揮它的優(yōu)點(diǎn)。