首頁 > web前端 > js教程 > 主體

理解Javascript閉包_javascript技巧

WBOY
發布: 2016-05-16 17:17:55
原創
885 人瀏覽過

閉包是ECMAScript一個很重要的特徵,但是卻很難用適當的定義來描述它。雖然閉包很難清晰地描述,但是,卻很容易創建,或者說,不小心創建。然而,閉包的存在其實是有一定的潛在問題的。為了避免「不小心」地創建閉包,以及更好地利用閉包的優點,有必要理解閉包的機制。

閉包的定義
 
關於閉包,有太多的定義,特別是有一些定義非常抽象,像這個:

A "closure" is an expression (typically a function) that can have free variables together with an environment that binds those variables.

大致是說閉包是一個表達式,擁有一些自由變量及定這些變量的執行環境。這種定義太書面化,反而難以理解。

還有另一個定義:
所有函數都是閉包。這個定義給我很大的迷惑,換句話說,由於Javascript沒有區塊級作用域,因此閉包一般指的是函數(想不出除了函數以外還有哪些方式可以構成閉包)。

這裡不想太多討論函數與閉包的關係,下面就給出我認為比較容易理解的定義吧。

首先,閉包的存在是基於作用域鏈。由於作用域鏈的機制,所有函數(即使全域函數)都能引用上下文執行環境中的變數(即free variables)。

其次,閉包內部必須有free variables。順便說下兩種變數1. Local variables (bound variables) 2. Non-local variables (free variables)

最後,在其上下文環境結束後仍然存在。即內部函數擁有比它的外部函數更長的生命週期。

 
關於閉包定義的解析
 
關於閉包定義的兩點,一直在考慮是不是必須同時滿足。

首先,如果閉包內部沒有free variables,也就是是說它沒有存取外部的變量,那麼就失去了閉包的意義。 (除非透過其他閉包改變了行為)因此,我認為free variables是必要條件。

其次,如果函數內部存在free variables,但是當其上下文環境銷毀後,它也跟著銷毀。可以想像內部函數,雖然存取了其外部函數變量,但是當外部函數執行完後也隨之回收。在這種情況下,閉包的討論也沒有意義。

 
來看兩個例子:

複製程式碼 程式碼如下:

var objectA = (function() {
        var localA = "localA";

    // 簡單的內部函數呼叫
        function innerFn( ) {
            localA = "innerChange";
        }

        }                return "空白";
       🎜>    })();

    objectA.getLocalA();

    ;

//console.log(objectA.getLocalA()); //錯誤: localA 未定義

 
    var objectB = (function() {
  
        return {
            getLocalB : function( ) {
         },

            updateGetLocalB : function(() {
  
                    return localB;
                };
            },

            updateLocalB : function() {
                localB = "changeLocalB";
            }
        };
    } )();

    控制台。日誌(objectB.getLocalB()); //empty
       // 透過其他閉包改變
    objectB.updateGetLocalB();

conpmmo. localB

    objectB.updateLocalB();

    console.log(objectB.getLocalB()); // 更改LocalB



閉包的優點和缺點


閉包的優點是閉包內部可以存取到定義它們的外部函數的參數和變數(除了this和arguments)。
閉包主要的問題那麼它會保存包含它的函數的作用域,因此比一般函數佔用更多的記憶體空間,因此不宜過度使用閉包。
閉包的應用

關閉包網關的應用場景就是透過保護內部訊號從而實現私有,例如模組模式。

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板