JavaScript閉包和模組模式[譯]

來源:互聯網
上載者:User
翻譯原文
  在JavaScript中一個最廣泛使用的設計模式是模組的模式。模組模式使用了JavaScript中的一個很棒的特性-閉包- 用來給你方法中的隱私一些控制這樣的第三方應用程式不能訪問私人資料或覆蓋它。在這篇文章中,我會教你什麼是閉包,它是如何工作的,以及如何利用它在你的JavaScript代碼中實現模組模式。
什麼是閉包?

閉包是JavaScript語言的一種構造。在JavaScript內所有變數都能在全域範圍內訪問,除非變數在函數內用var關鍵字聲明過。

variable1 = 1; //全域範圍var variable2 = 2; // 不在一個函數內: 全域範圍       function funcName() {  variable3 = 3; // 沒用var關鍵字聲明: 全域範圍  var variable4 = 4; //僅本地訪問}

view raw gistfile1.js This Gist brought to you by GitHub.

在一個函數內,你也可以獲得全域範圍和每個你所在的函數上級範圍的存取權限。換句話說,函數內聲明變數只能在函數包圍範圍內訪問。

var globalvar = 1; //全域範圍
function outer() {  var outervar = 2; // outer()範圍內
  function inner() {    var innervar = 3; // inner()範圍內    console.log(globalvar); // => 1    console.log(outervar); // => 2    console.log(innervar); // => 3  }
  console.log(globalvar); // => 1  console.log(outervar); // => 2  console.log(innervar); // => Reference Error引用錯誤;}
console.log(globalvar); // => 1console.log(outervar); // => Reference Error引用錯誤console.log(innervar); // => Reference Error引用錯誤
view raw gistfile1.js This Gist brought to you by GitHub.

每一個真正的JavaScript程式員應該知道這一點,除非他不思進取。知道這一點,你可以得出這樣的結論,用一種辦法來保持你所有代碼在全域命名空間外,是正確的。這特別有用,當你不想給任何人在未經許可的情況下有重寫你任何代碼的機會。你可以通過使用一個匿名函數(不給它命名,沒有被賦予一個變數)立即執行自身。這是眾所周知的自調用匿名函數(SIAF),雖然它可能是更準確地稱為立即調用的函數表達 (IIFE–讀做“iffy”) -作者Ben Alman。

(function() {    // 這函數立即執行,內部所有變數都是私人的}());
view raw gistfile1.js This Gist brought to you by GitHub.

緊接著右大括弧,是左右括弧於是函數將立即執行。圍繞整個函數運算式的括弧不是啟動並執行代碼必需的,但一般用作給其他開發人員的訊號,這是一個IIFE,而不是一個標準函數。有些人喜歡在前面加上一個驚歎號(!)或分號(;),而不是用括弧包起來。
用閉包的模組模式

知道了閉包是什麼,我們就可以使用模組模式建立對象。通過返回一個對象或變數並賦給一個函數外變數,這樣我們可以暴露任何希望暴露給外界的,我們可以有公開和私人的方法。

var Module = (function() {    // 下面函數是私人的,但可以被公開函數訪問    function privateFunc() { … };       // 返回一個對象賦予Module    return {        publicFunc: function() {            privateFunc(); // publicFunc可以直接存取privateFunc        }    };}());
view raw gistfile1.js This Gist brought to you by GitHub.

這就是模組模式的本質。您還可以使用參數傳入或縮寫常用資源的名稱:

var Module = (function($, w, undefined) {    // …    // return {…};}(jQuery, window));
view raw gistfile1.js This Gist brought to you by GitHub.

我傳入jQuery和window,被分別縮寫為$和w。注意我沒有傳任何東西作為第三個參數。這樣參數undefined將是undefined,所以它完美地工作。有些人這樣處理undefined是因為無論如何,它是可編輯的。所以,如果你判斷某某是否是undefined,但undefined可能已經改變,你的比較將不起作用。這種技術保證它將按預期工作。
透露模組模式revealing module pattern

透露模組模式是另一種方式來寫模組模式,需要更多點代碼,但有時更容易理解和閱讀。不同於在IIFE中定義所有私人變數並在返回對象中定義公開方法,你把所有方法都寫在IIFE中,只是“透露”哪些是你想公開在return語句內的。

var Module = (function() {    // 現在所有函數直接互訪    var privateFunc = function() {        publicFunc1();    };       var publicFunc1 = function() {        publicFunc2();    };       var publicFunc2 = function() {        privateFunc();    };       // 返回對象賦予Module    return {        publicFunc1: publicFunc1,        publicFunc2: publicFunc2    };}());
view raw gistfile1.js This Gist brought to you by GitHub.

對比正常的模組模式,透露模組模式有幾個優點:

  1. 所有函數的聲明和實現都在同一個地方,從而製造較少的混亂。
  2. 私人函數現在可以訪問公開函數,如果他們需要。
  3. 當一個公開函數需要調用另一個公開函數時,他們調用publicFunc2(),而不是用this.publicFunc2(),從而節省了幾個字元。

透露模組模式的唯一真正的缺點,正如我所說,是你必須寫更多的代碼,因為你必須先寫好函數然後再把它的名字寫在return語句內,儘管它最終可能會因為你可以忽略this.部分而節省你的代碼。
擴充模組模式

我想談的最後一件事是使用模組模式擴充已經存在的模組。這很常用,當為jQuery之類的庫做外掛程式,如下。

var jQuery = (function($) {    $.pluginFunc = function() {        …    }       return $;    }(jQuery));
view raw gistfile1.js This Gist brought to you by GitHub.

此代碼是相當靈活的,因為你甚至不需要var jQuery=或接近尾部的return語句。沒有它們jQuery仍將可以用這個新方法擴充。實際上返回和賦值整個jQuery對象,可能在效能上有損失,但是,如果你想在擴充jQuery的同時,分配jQuery到一個新的變數名,你只需改變第一行的jQuery為任何你想要的。
結論

朋友們,今天就到這裡。這些都是常見的技術和功能,即使你不使用這篇文章的知識,保留在你的腦海,以防萬一用到(很可能會發生)。。。最後,不要忘記分享和在下面評論。感謝和編碼快樂!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.