JavaScript模塊化思想

1. 首先,咱們須要明白爲何要用模塊化?html


功能都是爲了解決需求的。模塊化能夠帶來的優勢有如下幾點:
(1) 可維護性。舉個例子,若是咱們把未使用模塊化的代碼比做油和水混合在了一塊兒,模塊化以後的代碼就好像油和水的分層,油就是油,水就是水,這樣的代碼層次清晰,功能分明。彷佛用油和水必然分層的現象來指代JS模塊化的大勢所趨也很合適。
(2) 命名空間。這裏須要談到JS的做用域。又涉及到了做用域鏈。若是對做用域鏈不熟悉的同窗能夠移步個人另外一篇文章「 理解JavaScript中的做用域鏈」。JS中是靠函數來區分做用域的。每一個函數都有一個做用域鏈。若是咱們把全部的代碼都揉到一塊兒,代碼行數少還行,多了就不免會形成「命名空間污染」。
(3) 可複用性。當咱們明白了命名空間,藉助命名空間咱們就能夠實現對模塊代碼的封裝,這樣咱們就能夠在任何咱們須要這個功能的時候直接去引用這個功能模塊。

接下來,用個人JS代碼之路演示一下如何使代碼模塊化:
 
(1)原始時代:把全部的要用到的JS代碼都堆砌在該頁面的一對<script>標籤中。
1 function f1(){
2      //函數體
3 }
4 function f2(){
5      //函數體
6 }
這樣寫的缺點:代碼基本沒有什麼複用性能夠,應該還會存在和頁面隅合度過高的問題。還須要去考慮各類做用域的問題。
 
(2)古時代:思路就是把模塊寫成一個對象。好比咱們要寫一個能控制頁面音樂播放,中止,下一首,上一首的功能。就能夠封裝一個musicPlayer對象
複製代碼
 1 // 將基本的方法封裝起來
 2             var musicPlayer = {
 3 
 4                 var musicDom = null, //播放器對象
 5                 var musicList = [], //存放歌曲列表
 6 
 7                 // 初始化音樂播放器
 8                 var init =  function(){
 9                     
10                 },
11 
12                 // 添加一首歌曲
13                 var add = function(src){
14                    
15                 },
16 
17                 // 根據數組下標決定播放哪一首,索引index從0開始
18                 var play = function(index){
19                     
20                 },
21 
22                 // 暫停播放
23                 var stop = function(){
24                     
25                 },
26 
27                 // 下一首
28                 var next = function(){
29 
30                 },
31 
32                 // 上一首
33                 var prev = function(){
34 
35                 }
36             };
複製代碼
這時候,就已經能夠稱之爲一個模塊了,在全局做用域中,咱們只向window對象上綁定了一個musicPlayer對象,以後咱們就可使用musicPlayer加'.'的形式來調用裏面的方法。如「musicPlayer.init();」
這種方式也有一個缺點,就是咱們不能去控制咱們想暴露的內容,而且在外部能夠改寫musicPlayer對象的內部方法和變量。
 
(3)現代。包含IIFE(當即執行函數),放大模式,寬放大模式,輸入全局變量
  
  除了IIFE,其餘的三種我以前都沒有接觸過,在這裏簡單談談個人理解。
 
- IIFE(Immediately-Invoked Function Expression)
複製代碼
 1 // 建立一個當即執行的匿名函數
 2 // 該函數返回一個對象,包含你要暴露的屬性
 3 // 以下代碼若是不使用當即執行函數,就會多一個屬性i
 4 // 若是有了屬性i,咱們就能調用counter.i改變i的值
 5 // 對咱們來講這種不肯定的因素越少越好
 6 
 7 var counter = (function(){
 8   var i = 0;
 9 
10   return {
11     get: function(){
12       return i;
13     },
14     set: function( val ){
15       i = val;
16     },
17     increment: function() {
18       return ++i;
19     }
20   };
21 }());
22 
23 // counter實際上是一個對象
24 
25 counter.get(); // 0
26 counter.set( 3 );
27 counter.increment(); // 4
28 counter.increment(); // 5
29 
30 counter.i; // undefined i並非counter的屬性
31 i; // ReferenceError: i is not defined (函數內部的是局部變量)
複製代碼

從以上的代碼能夠看出,counter中其中並無i這個屬性,它只有return 中暴露出來的內容。這樣咱們就對i實現了私有。數組

 
- 放大模式
我對放大模式的理解就是把原函數看成參數傳遞到IIFE中,而後給原函數添加新的擴展方法,把擴展後的函數返回。就實現了對原函數的「放大」。
1 var module1 = (function (mod){
2   mod.m3 = function () {
3     //...
4   };
5   return mod;
6 })(module1);

在這個例子中,就給module1添加了一個新的方法m3並返回。模塊化

 

- 寬放大模式
寬放大模式就是在放大模式的基礎上新增了一個特性:IIFE的參數能夠是空對象。
1 var module1 = ( function (mod){
2   //...
3   return mod;
4 })(window.module1 || {});

IIFE傳入的參數:若是window.module1有定義,就傳入該參數,若是爲undefined就傳入一個空對象。函數

 

- 輸入全局變量
若是咱們要在IIFE內使用全局變量,最好把全局變量經過參數傳遞進去。
1 var module1 = (function ($, YAHOO) {
2   //...
3 })(jQuery, YAHOO);

如上所示的代碼將jQuery和YUI兩個庫的全局變量看成參數傳入了module1。spa

 

轉載http://www.javashuo.com/article/p-keapjmdx-g.htmlcode

相關文章
相關標籤/搜索