場景一:采用函數引用方式的setTimeout調用
閉包的一個通常的用法是為一個在某一函數執行前先執行的函數提供參數。例如,在web環境中,一個函數作為setTimeout函數調用的第一個參數,是一種很常見的應用。
setTimeout將要執行的函數(或者一段JavaScript代碼,但這不是我們要討論的情況)作為它的第一個參數,下一個參數是需要延遲執行的時間。如果一段代碼想通過setTimeout來調用,那么它需要傳遞一個函數對象的引用來作為第一個參數。延遲的毫秒數作為第二個參數,但這個函數對象的引用無法為將要被延遲執行的對象提供參數。
但是,可以調用另一個函數來返回一個內部函數的調用,將那個內部函數對象的引用傳遞給setTimeout函數。內部函數執行時需要的參數,在調用外部函數時傳遞給它。setTimeout在執行內部函數時無需傳遞參數,因為內部函數仍然能夠訪問外部函數調用時提供的參數:
function callLater(paramA, paramB, paramC) { /*使用函數表達式創建并放回一個匿名內部函數的引用*/ return (function () { /* 這個內部函數將被setTimeout函數執行; 并且當它被執行時, 它能夠訪問并操作外部函數傳遞過來的參數 */ paramA[paramB] = paramC; }); } /* 調用這個函數將在它的執行上下文中創建,并最終返回內部函數對象的引用 傳遞過來的參數,內部函數在最終被執行時,將使用外部函數的參數 返回的引用被賦予了一個變量 */ var funcRef = callLater(elStyle, "display", "none"); /*調用setTimeout函數,傳遞內部函數的引用作為第一個參數*/ hideMenu = setTimeout(funcRef, 500);場景二:將函數關聯到對象的實例方法
有很多這樣的場景:需要分配一個函數對象的引用,以便在未來的某個時間執行該函數。那么閉包對于為這個將要執行的函數提供引用會非常有幫助。因為該函數可能直到執行時才能夠被訪問。
有一個例子就是,一個javascript對象被封裝用來參與一個特定DOM元素的交互。它有doOnClick、doMouseOver以及doMouseOut方法。并且想在DOM元素上對應的事件被觸發時執行這些方法。但是,可能會有關聯著DOM元素的任意數量的javascript對象被創建,并且單個的實例并不知道那些實例化它們的代碼將如何處理它們。對象實例不知道怎樣去“全局”地引用它們自己,因為它們不知道哪個全局變量(如果存在)的引用將被分配給它們。
所以,問題是執行一個與特定javascript對象實例關聯的事件處理函數,并且知道調用那個對象的哪個方法。
接下來的一個例子,在有元素事件處理的對象實例的關聯函數上使用一個簡單的閉包。通過傳遞event對象以及要關聯元素的一個引用,為事件處理器分配不同的對象實例方法以供調用。
新聞熱點
疑難解答
圖片精選