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