2011-02-26 212 views
0

下面是一個JavaScript應用程序模塊化佈局的示例。我想開始爲我的工作使用這樣的結構。我正在努力讓自己的頭腦如何工作,並且需要了解如何從不同的模塊中調用一個模塊中定義的函數?這絕對是佈局JavaScript重型應用程序的下注方式嗎?Javascript模塊佈局:如何從另一個模塊中調用一個模塊中定義的函數?

window.MainModule = (function($, win, doc, undefined) { 
    var modules = {}; 

    // -- Create as many modules as you need ... 
    modules["alerter"] = (function(){ 
     var someFunction = function(){ alert('I alert first'); }; 

     return { 
      init: someFunction 
     }; 
    }()); 

    modules["alerter2"] = (function(){ 
     var someFunction = function(){ alert('I alert second'); }; 

     return { 
      init: someFunction 
     }; 
    }()); 

    return { 
     init: function(){ 
      for (var key in modules){ 
       modules[key].init(); 
      } 
     } 
    }; 
}(jQuery, this, document)); 

$(window.MainModule.init); 
+0

您應該考慮閱讀「JavaScript:The權威指南,第5版」的第10章「模塊和命名空間」。 – 2011-02-26 10:46:59

+0

Tbh。這是一個可怕的模式。在包裝器中定義模塊,啓動所有模塊。沒有辦法外部添加/刪除模塊,沒有辦法決定要運行什麼和不運行......這很愚蠢。不提多餘的自我執行功能。使代碼看起來模塊化語義不模塊化... – BGerrissen 2011-02-26 11:15:32

+0

@BGerrissen所以任何幫助,將不勝感激... – wilsonpage 2011-02-26 11:18:26

回答

3

模塊化與RequireJS

module1.js

define(["dependency"] , function(dep){ 

    return { 
     speak: function(){ 
      alert(dep.message); 
     } 
    } 

}); 

dependency.js

define({ 
    message: "Hello world!" 
}); 

impl.js

if ($(".someCssExpression").length) { 
    require([ "module1" ] , function(mod){ 

     mod.speak(); 

    }); 
} 

的index.html

... 

<script src="require.js" data-main="impl"></script> 

... 

你的文件結構將是模塊化的。 您的實施將是模塊化的。 沒有笨拙的命名空間或怪異的構造,使其感覺有組織。

採取了一些習慣,但完全值得。

還可以閱讀:

+0

謝謝我在本週末要求我自己requireJS來徹底排除這個問題。慢慢到達那裏!很難在這樣一個自認爲的主題中得到正確的答案,但我相信要求JS在模塊化佈局方面爲您做了很多工作。如果我錯了,請糾正我的錯誤... – wilsonpage 2011-02-26 17:22:28

1

爲了訪問任何東西,它需要在您呼叫的範圍內可用。 「模塊」 - 或者就此而言任何封裝方法 - 在JS中總是意味着「功能」。模塊只是一個匿名(匿名)函數。因此,要從函數A中訪問在另一個函數B(模塊)中定義的元素,它必須在GLOBAL SCOPE中(在瀏覽器中:窗口對象)中可用,或者它必須以其他方式獲得訪問權。通過一些函數調用接收到引用。對於後者,YUI3([http://developer.yahoo.com/yui/3/])是一個有趣的例子,你的應用程序在全局範圍內沒有任何東西可用(我認爲YUI3是迄今爲止最好的JS框架之一對於嚴重的軟件開發,也絕對要檢查出http://developer.yahoo.com/yui/theater/,尤其是任何來自道格拉斯克羅克福德的視頻,這是一個Javascript上帝(我通常不會給出這些陳述) 你必須記住的Javascript是C語言中的一部分是由編譯器完成的,現在發生在運行時,對於像返回一個函數的立即函數調用(通過使用閉包來封裝)的事情,你應該記住,該代碼在加載期間只運行一次,但在運行期間,會執行完全不同的代碼 - 這取決於加載代碼的執行情況。

在您的示例中,window.MainModule = ...之後的函數在加載JS代碼時執行。請注意,window.MainModule不指向該功能! 相反,正如我所說的那樣,該函數在加載時執行,並且RESULT被分配給window.MainModule。結果是什麼?那麼,只有一個返回語句,它返回和對象,並且該對象只有一個屬性「init」指向一個匿名函數。

但是,在返回該對象之前,該函數會在其局部範圍內創建一個指向對象的變量「modules」。該對象有兩個屬性,並且這些屬性的賦值方式與window.MainModule的賦值方式相同,因此總共有三個閉包。

那麼樣之後,你有一個全局變量

window.MainModule = { 初始化:函數(){...}

那麼樣之後,你有一個全局變量

窗口。 MainModule = {0121}init:function(){...} }

在函數執行的最後一行。

}

在函數執行的最後一行。

雖然這個例子沒有多大意義,因爲你沒有真正封裝任何東西。您可以使用雙指針提供私有函數:從init到局部變量some​​Function,不會隱藏任何內容。查看上面的URL(Yahoo Developer Theater)以獲得更好的示例和非常詳盡的解釋。即使你從不碰YUI3--尤其是來自D. Crockford的視頻是JS的一般知識,它也是必須的。

1

嗯,嗯.. 這一切都depands您從您的應用程序所需要的。 只要你碰到gui,我會建議堅持jQuery插件。

您可以使用像雅虎這樣的命名空間模式,併爲您的 應用程序創建一個很棒的框架。

你可能不需要你的模塊在每個頁面上運行,就像你在實例化主模塊時一樣(除非你在你的網站上每個頁面都有一個小部件)。

當您完成將您需要的所有操作從JavaScript抽象爲函數和模塊後,構建一個模塊,根據每個頁面/操作/任何需要時加載邏輯。

順便說一下,您可以始終使用mootools開發OO風格,這是真的無窮無盡的。 這一切都歸結到你的應用程序需要

我會真的建議您觀看道格拉斯克羅克福德的一些講座(由於我之前已經說明)和here是有關模塊的一個很好的文章,可以幫助你瞭解它進一步。 祝你好運!

相關問題