理解Javascript的閉包

來源:互聯網
上載者:User

  先來看兩段代碼,若是你不能完全理解它們的原理,則本文對你還是有一點參考作用的。

  首先是我寫的一段用來類比私人成員的代碼:

function Foobar(parameter) {var privateVariable = "I'm private Variable";var privateFunction = function() {return "I'm privateFunction and privateVariable is : " + privateVariable;}this.publicVariable = "I'm public Variable";this.publicFunction = function() {document.write("parameter : " + parameter + "<br />");document.write("privateVariable : " + privateVariable + "<br />");document.write("privateFunction : " + privateFunction() + "<br />");document.write("publicVariable : " + this.publicVariable + "<br />");}}var foobar = new Foobar("I'm paramter");foobar.publicFunction();document.write("typeof(foobar.privateVariable) : " + typeof(foobar.privateVariable) + "<br />");document.write("typeof(foobar.privateFunction) : " + typeof(foobar.privateFunction) + "<br />");document.write("typeof(foobar.publicVariable) : " + typeof(foobar.publicVariable) + "<br />");document.write("typeof(foobar.publicFunction) : " + typeof(foobar.publicFunction) + "<br />");

  輸出內容:

parameter : I'm paramter
privateVariable : I'm private Variable
privateFunction : I'm privateFunction and privateVariable is : I'm private Variable
publicVariable : I'm public Variable
typeof(foobar.privateVariable) : undefined
typeof(foobar.privateFunction) : undefined
typeof(foobar.publicVariable) : string
typeof(foobar.publicFunction) : function

  可以看到,privateVariable和privateFunction都被成員的隱藏了起來。再看一段來自dojo類庫的代碼:

var getImgInPositionedDivHtml = (function(){    var buffAr = [        '<div id="',        '',   //index 1, DIV ID attribute        '" style="position:absolute;top:',        '',   //index 3, DIV top position        'px;left:',        '',   //index 5, DIV left position        'px;width:',        '',   //index 7, DIV width        'px;height:',        '',   //index 9, DIV height        'px;overflow:hidden;\"><img src=\"',        '',   //index 11, IMG URL        '\" width=\"',        '',   //index 13, IMG width        '\" height=\"',        '',   //index 15, IMG height        '\" alt=\"',        '',   //index 17, IMG alt text        '\"><\/div>'    ];    return (function(url, id, width, height, top, left, altText){        buffAr[1] = id;        buffAr[3] = top;        buffAr[5] = left;        buffAr[13] = (buffAr[7] = width);        buffAr[15] = (buffAr[9] = height);        buffAr[11] = url;        buffAr[17] = altText;        return buffAr.join('');    }); //:End of inner function expression.})();

  這是來自於dojo類庫的一段代碼,基本上,getImgInPositionedDivHtml是一個用來建立絕對位置div的html代碼。這個div是有固定的模式的,變動的只是具體的一些屬性,所以它用了一個buffAr來承載這個模式,getImgInPositionedDivHtml在接收到具體的屬性值(url, id, width, height, top, left, altText),就會把它放到buffAr的相應位置,再返回buffAr的join後的字串。而無論getImgInPositionedDivHtml被執行多少次,buffAr只會被建立一次,類似於靜態成員的行為。當然,在真正的面向對向語言中,我們是不能這麼做的,因為還要考慮到安全執行緒的問題,有點扯遠了。

  這兩段代碼,都是利用了Javascript特有的閉包來實現各自的效果,什麼是閉包呢?

  我們知道,變數有範圍的概念,在一個函數體中,使用var聲明局部變數只在函數體中能被引用,而在函數外部則是無法訪問該變數的。理論上,局部變數會在函數執行完畢之後被釋放,除非它有在其它地方被引用(也很有可能是在指令碼被卸載的時候才統一回收的,但這不影響它能否被引用),最容易理解的就是被return回上層調用:

function getLocalVar() {var localVar = "I'm local var";return localVar;}var globalVar = getLocalVar();

  範圍的概念在很多程式設計語言中都有存在,在Javascript中一樣也有,特別的地方就在於Javascript是一種動態語言,它可以定義內嵌函數。當你在一個函數內部定義一個新的函數時,內嵌函數就可以引用該函數的局部變數。:

function OutterFunction() {var outterVar;function InnerFunction() {return outterVar;}}

  當OutterFunction每次被調用時,解譯器會為它分配一個棧區,所有的局部變數都會被放到這個棧區(閉包開始),棧區內的局部變數都是相互可見的,而InnerFunction也是局部變數之一,所以當OutterFunction執行完畢退出以後,InnerFunction依然可以訪問到其他的局部變數(閉包形包)。要注意的是InnerFunction每次都被重新建立,每次返回都是不同的。換句話說,閉包就是指返回出來的InnerFunction可以訪問到OutterFunction的局部變數這種情形

  理解併合理地使用閉包可以使程式更加靈活和優雅。很多Javascript類庫都有閉包的應用,所以,如果需要經常和Javascript打交道的話,閉包是無法繞過的概念。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.