2012-06-26 84 views
2

我使用的JavaScript模塊模式,並且有這個至今:打破我的JavaScript到模塊,我做對了嗎?

var APP; 
if(APP == undefined) { 
    APP = {}; 
} 

APP = (function() { 
    var userId = -1; 
    var privateVar = ''; 

    var _init = function($userId) { 
     userId = $userId; 
    }; 
    var _publicMethod = function($id){ 
     privateVar = id; 
    }; 
    return { 
     init = function($userId) { 
      _init($userId); 
     }, 
     publicMethod = function($id) { 
      _publicMethod($id); 
     } 
    }; 
})(); 

我再有一個共同的utils的模塊:

APP.utils = (function(){ 

})(); 

然後每頁我計劃具有模塊,所以我不wireup事件(點擊按鈕等),沒有理由在哪裏,這些DOM元素不活動頁面存在:

APP.homePage = (function(){ 
    return { 

    }; 
})(); 

因此,每個模塊都會有一個init()方法ŧ我會在頁面上調用運行必須運行的事情(例如,接線,事件,設置好比說用戶id等變量):

$(document).ready(function() { 
    APP.init(<%= user.id %>); 
    APP.homePage.init('abc'); 
}); 

所以,現在如果文件受到太大,我能打破他們分成不同的文件也。

  1. 如果什麼一個模塊需要調用另一個,我想這個工作的唯一途徑是通過公共API有權這樣做嗎? 例如如果homePage需要userId,我應該在homePage#init方法中傳遞它嗎?

  2. 我的編碼風格如何,任何不被認爲是最佳實踐的明顯風格?

  3. 對此方法有何評論?一般情況好嗎?
+0

你還應該看看require.js。 – Thilo

+0

可能是一個問題http://codereview.stackexchange.com – Bergi

回答

2

如果一個模塊需要調用另一個模塊會怎麼樣,我猜這個工作的唯一方法就是通過public api來執行此操作嗎?

例如如果homePage需要userId,我應該在homePage#init方法中傳遞它嗎?

不,我不會在所有模塊中重複userId的代碼,而是在默認模塊中爲它提供一個公共getter。

上編碼

此代碼

var APP; 
if(APP == undefined) { 
    APP = {}; 
} 

APP = ... 

任何意見,還是蠻有用的。你不需要在這裏檢查對象的存在,因爲你無論如何都會覆蓋它。這也意味着這個代碼必須是第一個執行的代碼。如果你想使模塊獨立於加載順序,你需要使用類似

var APP = (function(a) { 
    var private_vars; // ... 
    a.init = ... 
    a.publicMethod = ... // add them to the object instead of creating new one 
    a.getPrivate = function() { 
     return private_vars; 
    }; 
    return a; 
})(APP || {}); // create one iff not already existing 

// other file: 
var APP = APP || {}; 
APP.utils = ... // add object to namespace 

代碼

var _publicMethod = function($id){ 
    privateVar = id; 
}; 

看起來有點奇怪。首先,下劃線通常表示對象的半私有(public-but-not-to-used)屬性,不應該用於變量名稱。這不是這種情況,因爲該功能將作爲APP的「publicmethod」屬性公開。如果你想要的話,在那裏使用下劃線。其次,這裏不需要使用函數表達式。代碼位於模塊的本地作用域中,並且使用函數聲明都可以在該作用域中的任何地方使用,並允許命名該函數。你應該使用

function publicMethod($id) { 
    privateVar = id; 
} 
a.publicMethod = publicMethod; 
+0

你可以舉一個暴露公共財產的例子,在默認模塊中,我只是添加了方法,所以想確保我做得很好,謝謝! – Blankman

+0

查看具有變量的示例。公共屬性被添加到閉包中的模塊。 – Bergi

+0

是$爲參數良好的做法?謝謝!公共屬性 – Blankman

1

在我看來,模塊模式是組織代碼的一種非常好的方式。要回答你的問題:

1)是的,你的模塊只能訪問已經暴露在它們返回的對象中的其他模塊的方法和屬性。

2)我認爲你的編碼風格看起來不錯。我會做出這些變化:

APP = (function() { 
    var _userId = -1; 
    var _privateVar = ''; 

    var init = function($userId) { 
     _userId = $userId; 
    }; 
    var publicMethod = function($id){ 
     _privateVar = id; 
    }; 
    return { 
     init : init, 
     publicMethod : _publicMethod 
    }; 
})(); 

首先,下劃線通常用來表示「私有」屬性或方法。其次,你可以避免返回對象中的額外函數,並直接指向你關心的方法或屬性。這通常被稱爲「揭示模塊模式」,因爲即使公共方法沒有在返回的對象中定義 - 它們只是被引用。

3)這種方法絕對是封裝代碼的好方法。您可以獲得私有和特權方法的好處,並且通常最終會獲得更好的API,因爲您只公開需要公開的內容。

幹得好。