造輪子和用輪子:快速入門JavaScript模塊化

前言

都說「不重複造輪子」,就像iPhone——它除了打電話還能夠播放音樂——可是工程師不用從零開始作一個音樂播放功能,也許只要在iPhone的系統中整合一個ipod。前端

前端開發亦是如此,最理想化的開發狀態就是,工程師只寫核心業務代碼,其餘通用的功能和組件均可以無縫加載別人寫好的代碼,就像不少那樣。程序員

但是實際狀況是,有個糟糕的 iPhone 工程師,他搞混了 iPhone 和 ipod 的系統,甚至把 iPhone 的 Home 鍵和 iPod 的音量鍵焊在同一個。瀏覽器

還有一些糟糕 JavaScript 開發者,一不當心聲明瞭全局變量,混亂了「命名空間」,都讓協做開發變得不那麼友好,抑或他開發了一個通用模塊,用戶們卻發現載入了他的代碼以後,用戶本身的代碼被他搞得一團糟。安全

原始人寫法

好比下面這段代碼:模塊化

var mylove = "coding";

function getLove() {
  return mylove;
}

function sayLove(thing) {
  console.log(thing);
}

console.log(getLove());//>>> coding
sayLove('girl');//>>> girl

在 window 對象下聲明瞭一個變量mylove,而後使用getLove()函數去獲取這個變量,使用setLove()修改這個變量。
恩,功能是實現了。只是這樣作以後,說不定何時你因爲粗心又在某個地方聲明瞭一次mylove,而你的粗心同事也不知道會在什麼地方寫了一個同名函數——也許有3個參數的setLove()函數。函數

對象封裝寫法

怎麼辦呢?你獲取想到了,把這些變量和函數都寫在一個對象裏:this

var loveThing = {
  mylove : "coding",
  getLove :function() {
    return this.mylove;
  },
  sayLove : function(thing) {
    console.log(thing);
  }
}

console.log(loveThing.getLove());//>>> coding
loveThing.sayLove('girl');//>>> girl

這種寫法已經有點模塊的樣子了,一下就能看出這幾個函數和變量之間的聯繫。缺點在於全部變量都必須聲明爲公有,因此都要加this指示做用域以引用這些變量。更危險的是,在對象以外也能輕鬆更改裏面的參數:code

loveThing.mylove = "sleeping";
console.log(loveThing.getLove());//>>> sleeping

當即執行函數

我向來不憚以最壞的惡意揣測程序員,你永遠想不到你的 partner 會不會真的在其餘地方修改了你的參數,也不知道本身是否會在不經意間修改了他的。咱們必須在他下手以前——讓本身的模塊先執行掉,不給對方可趁之機。此時使用一種叫作當即執行函數的辦法,能夠避免暴露私有成員。對象

var loveThing = (function(){
  var my = {};
  var love = "coding";
  my.getLove = function() {
    return love;
  }
  my.sayLove = function(thing) {
    console.log(thing);
  }
  return my;
})();

console.log(loveThing.getLove());//>>> coding
loveThing.sayLove('reading');//>>> reading

咱們試着獲取裏面的變量:繼承

console.log(loveThing.love);//>>> undefined

果真,外部根本看不見裏面的零件,只能使用提供的接口。這樣才能保證私有變量的安全。

放大模式

固然,一個項目要用到模塊化的時候,說明這個項目足夠大足夠複雜,一個模塊可能須要繼承另外一個模塊,或者擴充模塊,這時候須要使用放大模式

var loveThing = (function (o){
  o.sayOK = function () {
    console.log('OK');
  };
  return o;
})(loveThing);

loveThing.sayOK();//>>> OK!

寬放大模式

但是,瀏覽器是一個不按常理出牌的環境,你永遠不知道本身引用的模塊是否已經加載。萬一我以前的loveThing沒有被加載,上面這段代碼就會報錯了(找不到對象)。解決方法就是所謂寬放大模式

var loveThing = (function (o){
  o.sayOK = function () {};
  return o;
})(loveThing || {});

與以前惟一的不一樣就是參數能夠爲空對象。

至此,最基本的JavaScript模塊化寫法你已經學會了,相信你也體會到本身原來的寫法有什麼不足。

受篇幅限制,本篇入門到此結束,我會在下一篇討論流行的模塊化規範。

相關文章
相關標籤/搜索