改善javascript程式碼結構
首先看下常規開發中javascript非結構化組織程式碼
function appInit () { //程式初始化操作 } function appModule1 () { //程式功能模組1 } function appModule2 () { //程式功能模組2 } function appModule3 () { //程式功能模組3 } $( document ).ready(appInit )
從技術角度看,這種程式碼方式並沒有任何錯誤,但是通過下圖可以發現這些函式都是建立在全域性名稱空間下
若在全域性名稱空間中建立很多變數很快會導致嚴重的問題、比如在全域性名稱空間中定義了名為i、_或$的變數。
如何改善呢?
1、使用一個單例建立一個應用程式名稱空間
var myApp = { init : function () { //程式初始化操作 }, appModule1 : function () { //程式功能模組1 }, appModule2 : function () { //程式功能模組2 }, appModule3 : function () { //程式功能模組3 } } $( document ).ready(myApp.init)
對於上面的新結構,開啟chrome檢視window下的屬性時僅看到單個變數myApp,這中方式極大的降低了變數名衝突的可能性。
這一模式允許多個開發人員跨越多個檔案,在單個應用程式名稱空間之下進行協同開發。從程式碼結構角度來說,可以將網站的每一部分拆成獨立檔案。比如本例中的common.js、
appModule1.js、 appModule2.js和 appModule3.js。每個開發人員都有一個自己負責的網站部分和相應的javascript檔案,開發人員只需要關注自己的檔案,不需要擔心會發生衝突。
common.js var myApp = { common : { init : function () { //初始化應用程式通用程式碼 } } } appModule1.js myApp.appModule1 = { init : function () { //初始化程式碼 }, update : function () { //更新模組1的程式碼 }, render : function () { //呈現模組1的程式碼 } } appModule2.js myApp.appModule2 = { init : function () { //初始化程式碼 }, update : function () { //更新模組2的程式碼 }, render : function () { //呈現模組2的程式碼 } } appModule3.js myApp.appModule3 = { init : function () { //初始化程式碼 }, update : function () { //更新模組3的程式碼 }, render : function () { //呈現模組3的程式碼 } }
2、Module模式
模組模式是單例的一種變種,增強了單例模式提供的封裝性,並增加了建立私有方法和私有屬性的功能
模組模式包含三個主要元件:一個與前面例子類似的名稱空間、一個立即執行函式和函式返回物件,該返回物件包含公有方法和公有屬性,js程式碼如下:
//app的名稱空間。傳入jquery物件以縮短查詢過程 var myApp = function( $ ){ //私有變數和方法 var message = " i am a module "; function multiplier (x,y) { return x * y; }; //返回物件包含公有屬性和方法 return { init:function(){ //初始化app }, prop : '42', getProduct : function(){ //訪問私有方法 return multiplier(2,3); }, shareMessage : function (arg){ //對私有屬性進行限制訪問 if(arg == "admin"){ return message; } else { throw new Error("No access"); } } } }(jQuery)
控制檯中測試如下:
擴充套件該模式以增加更多的模組也非常簡單。如下程式碼:
myApp.module1 = function($){ //私有變數和方法 var config = { "color":"red", "title":"module1", "width":"20px" }; return { init:function(){ //初始化module1 }, updateConfig : function(obj){ config.color = obj.color || config.color; config.title = obj.title || config.title; config.width = obj.width || config.width; }, render:function(){ var $module1 = $("#id"); $module1.text(config.title) .css({"width":config.width,"color":config.color}) } } }(jQuery)
該程式碼描述了一個module1模組,它包含一個私有配置物件和一個公共方法,該公有方法允許根據一組預定義條件獲得對module1配置的訪問,類似於java中private和public關鍵字的使用。在js開發中,並非所以時候都需要使用這種保護訪問,但當我們需要實現這樣功能時,使用模組模式是非常重要的。