前言
實際項目中,使用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