都說「不重複造輪子」,就像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模塊化寫法你已經學會了,相信你也體會到本身原來的寫法有什麼不足。
受篇幅限制,本篇入門到此結束,我會在下一篇討論流行的模塊化規範。