[JavaScript] JavaScript進階系列 - 使用require高效組織代碼結構


前言


  實際項目中,使用JavaScript開發面臨着一個很大的問題,就是代碼的可控性差。隨着項目的進展,JavaScript代碼量也許會爆炸式增長,如果不加以控制,那么潛在的問題將越積越多。在此說明下,很多人認為JavaScript難登大雅之堂,就是一門簡簡單單的腳本語言,覺得能用就行,不屑於深入理解。這也是為什么國內的很多項目,JavaScript部分混亂,安全性可擴展性很差的原因。其實JavaScript真的不簡單。

 

使用require管理代碼結構


  require代碼如下:

 1  var require, define;
 2 ( function() {
 3    var modules = {};
 4   
 5    function build(module) {
 6      var factory = module.factory;
 7     module.exports = {};
 8      delete module.factory;
 9     factory(require, module.exports, module);
10      return module.exports;
11   }
12   
13   require =  function(id) {
14      if (!modules[id]) {
15        throw 'module ' + id + 'not found';
16     }
17      return modules[id].factory ? build(modules[id]) : modules[id].exports;
18   };
19   
20   define =  function(id, factory) {
21      if (modules[id]) {
22        throw 'module ' + id + ' already defined';
23     }
24     
25     modules[id] = {
26       id: id,
27       factory: factory
28     };
29   };
30   
31   define.remove =  function(id) {
32      delete modules[id];
33   }
34   
35 })();

  不管你相不相信,短短的35行代碼完全可以幫助你管理好你的代碼。下面我們來詳細的解讀下這段代碼,

  1. 第 1 行 定義了兩個全局變量 require 和 define

    define: 用於定義代碼模塊,就像Java里面的類,封裝了方法和屬性,定義的代碼模塊中封裝了一些列的方法和屬性,以便調用。

    require: 用於調用封裝好的代碼模塊,就像Java里面在一個類中,可以調用另一個類中的屬性和方法,require就用於創建一個模塊的對象,供其他模塊調用它里面的方法和屬性。

  2. 第 2 ~ 35 行 詳細給出了define, require以及define.remove三個方法的邏輯。

  3. 第 3 行 定義一個局部變量 modules ,用於緩存所定義的所有模塊。

  4. 第 20 行 定義了 define 方法, 此處有兩個參數 id 和 factory,

    id: 該參數的類型是String, 用於定義模塊的組織結構,必需唯一,你可以定義為 "cnblogs/utils" 或者 "cnblogs/view"等

    factory: 該參數的類型是Function, 用於定義模塊具體的代碼實現

  5. 第 31 行 定義了 define.remove 方法, 該方法用於刪除某個模塊

  6. 第 13 行 定義了 require 方法, 該方法用於加載某個模塊

  7. 第 5 行定義了 私有方法 build ,第一次看這個方法你會覺得很奇怪,里面的 factory, exports等會讓你感到丈二和尚摸不着頭腦,我先簡要介紹下,factory就是 define 方法中的參數 factory, exports在這兒你可以理解為需要分享出來的 API。

  下面我們通過一個例子來好好的理解下。

 1 define('cnblogs/utils',  function(require, exports, module) {
 2    var utils = exports;
 3   
 4   utils.isArray =  function(a) {
 5      return Object.prototype.toString.call(a) == '[object Array]';
 6   };
 7   
 8   utils.alert =  function(msg) {
 9      if (alert) {
10       alert(msg);
11     }  else  if (console && console.log) {
12       console.log(msg);
13     }
14   };
15 });
16 
17 define('cnblogs/view',  function(require, exports, module) {
18    var utils = require('cnblogs/utils');
19    var views = {
20     showWebView:  function() {
21       utils.alert('Show WebView...');
22     },
23     hideWebView:  function() {
24       utils.alert('Hide WebView...');
25     }
26   };
27   module.exports = views;
28 });
29 
30  var cnBlogsView = require('cnblogs/view');
31 cnBlogsView.showWebView();
32 
33  /*
34  define.remove('cnblogs/view');
35  var cnBlogsView1 = require('cnblogs/view');
36  cnBlogsView1.showWebView();
37  */

  備注:

    該例子中我們創建了兩個模塊"cnblogs/utils"和"cnblogs/view"。"cnblogs/utils" 用於定義項目中的一個工具方法,該模塊類似於Java中的工具類。"cnblogs/view"用於定義項目中和視圖相關的公共方法,並且在該模塊中調用"cnblogs/utils"模塊中的"alert"方法。

  講解:

  1. 第 1 ~ 15 行使用define方法定義"cnblogs/utils"模塊, 第 2 ~ 14  行是define方法 factory 參數的函數體內容,該factory函數定義了3個參數

  require: 可看做全局變量require

  exports: 類型為Object,用於封裝需要分享出來的方法和屬性

  module: 可看作該模塊本身的一個引用

  第 2 行 var utils = exports; 表明utils對象將被exports出來,例如第 18 行, var utils = require('cnblogs/utils'); 該utils就是exports對象即第 2 行中的utils對象。

  2. 第 17 ~ 28 行定義了 "cnblogs/view" 模塊,此處我們重點看下第 18 行和第 27 行,第 18 行使用require方法獲取"cnblogs/utils"模塊信息,第 27 行 module.exports = views; 等價於使用 var views = exports;

  3. 第 30 ~ 37 行用於測試。

 

作者信息:

QQ: 1321518080

Email: hucaijun520.ok@163.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM