2011-10-07 135 views
10

我希望通過將其分割成不同的文件,併爲每個文件提供一個'sub'命名空間。Javascript命名空間

subA.js

if(typeof ex == "undefined") { 
    var ex = {}; 
} 

ex.subA = function() { 
//all functions of subA here 
} 

而同爲subB的等

目前,我有1個文件,ex.js

var ex = (function() { 
    //private vars/funcs 
    return { 
     //public vars/funcs 
    } 
})(); 

它看起來像我應該將大部分函數移動到subA.js和subB.js,但在開始時仍然包含ex.js,其中包含subA.js和subB.js a fterwards。

我有很多問題。

  1. 我很難記住我是如何製作初始命名空間文件ex.js.它看起來像匿名函數是最初使所有內容都是私有的,但我不記得爲什麼它需要用圓括號括起來,然後直接用();執行。

  2. 從q1開始,我的子文件應該與ex.js的格式相同,即將anon函數包裝在括號中並立即執行?

  3. 看起來子文件只能訪問ex的公共功能,這是真的嗎?如果是這樣,我怎樣才能讓我的子文件訪問私有函數呢?

  4. 在我的HTML文件中,在我的document.ready函數(jQuery的),我應該初始化前變量或可我首先要

$(document).ready(function() { 
    ex.doSomething(); 
    ex.doSomethingElse(); 
}

單獨調用每個函數兩者有什麼不同?我認爲,當包含ex.js時,會立即創建一個全局變量ex(由於匿名函數會立即執行),所以我不需要在document.ready中重新定義它。

  1. 是第一個if語句在subA.js中與var ex = ex || {};有什麼不同嗎哪個更好?

  2. 你用什麼js代碼風格標準?

如果你通讀了這一切,你已經得到了讚賞,歡呼聲。

+0

你最好給你的'typeof'比較加引號,並刪除'!ex':'if(typeof ex ==「undefined」)''。 –

+0

@Rob W不要一些瀏覽器返回爲空,而不是'undefined'?雅虎名稱間隔代碼使用!ex – Michael

+0

當一個變量以前從未定義過時,'typeof'將返回'「undefined」'。但是,某些屬性在執行檢查時可以返回null('typeof null ===「object」')。 –

回答

5

1. function(){ return{}}是一個封閉到「隱私」添加到變量和函數,你不也將盡快加載不想在任何其他地方訪問,但在該功能的範圍內。函數(function(){})附近的括號創建一個函數表達式。它們被使用,因爲當你嘗試立即執行一個函數function(){}()而不傳遞任何參數給()時,解析器會報錯。

2.如果你想subA或任何其他擴展對象有自己的子功能,那麼是的,你必須聲明它,但不是一個clousure然而並非必然。

你可以做

ex.subA = function(x, y){ 
    return x+y; 
} 

可以稱之爲var sum = ex.subA(2, 3);

或者你也可以做

ex.subA = (function(){ 

    return { 
     add: function(x, y){ 
      return x+y; 
     }, 
     multiply: function(x, y){ 
      return x*y; 
     } 
    } 
})(); 

然後調用它var sum = ex.subA.add(2, 3); var multiplication = ex.subA.multiply(2,3);

有很多方法可以做到這一點。

3.是的,這是事實。你可以公開私人功能。關閉不會允許任何其他方式來做到這一點。

4.如果你想別名,是的,你可以將它分配給一個變量。但是,沒有必要。它會很好地描述它的方式。

閱讀Essential JavaScript Namespacing Patterns瞭解JavaScript命名空間中的一些基本原理和模式。


是第一如果subA.js從VAR前=前有什麼不同聲明|| {};哪個更好?

首先,if語句應該是if(typeof ex == 'undefined')typeof返回一個字符串。沒有任何需要檢查ex是否爲假。

是的,它是不同的。如果已經定義了變量ex,if語句將不會執行任何變量賦值。因此,if語句更好。

你用什麼樣的js代碼風格標準?

取決於項目的範圍,但主要是深層次的對象用輔助函數進行擴展。

+0

感謝您的真棒回覆。我有幾個跟進問題。對於'if(typeof ex =='undefined')'語句,我聽說有些瀏覽器將未定義的變量作爲'undefined'返回,但其他瀏覽器將其返回爲null,這就是爲什麼它有2個部分。
隨着代碼樣式標準,我更多地討論了函數的命名等,但我對這個使用助手函數擴展的深層對象感興趣。你能詳細說明一下嗎?是不是像jQuery.extend?你會認爲使用它爲每個添加額外的js文件而不是不同的命名空間嗎? – Michael

+0

@Michael 1)我從來沒有遇到一個瀏覽器,它賦予一個未定義的變量爲null。不過,我在JavaScript中相當新穎。雖然,我認爲你已經閱讀過關於NULL被視爲一個對象,這是另一回事。如果你能給我一個參考,我會很樂意閱讀它。 2)是的,它就像jQuery.extend。我認爲這一切都歸結於項目的規模。如果你有一個小項目,你可以手動添加命名空間,就像你一樣。如果這是一個大項目,則需要某種幫助器來擴展名稱空間。 – Shef

+0

我認爲你是對的,我必須與別的東西混淆。 – Michael

0

對於問題1和3:

在ex.js的閉合樣式defenition將允許那些公共功能和VAR /暴露。

我的想法是,最好從anomyous函數返回「ex」與我們需要暴露的函數和變量。

for Q3。在返回函數中定義和使用的那些(私有)變量仍然可用於該函數,並且可以通過公開函數(閉包的屬性)使用。

如果包含的外部腳本位於文件的頂部或部分,則ex應該在document.ready之前可用,並應該立即可用。

你讓我想:)當我進一步挖掘到這一點時,將更新帖子。非常好的問題。 :)

2

在你設計時,你將無法訪問在該lambda函數中定義的私人變量/ funcs,因爲它只返回一個對象,或者你想使用new

1.如果沒有()ex是函數而不是函數返回的對象。

2.no需要,除了你想傳遞一些參數進行初始化。例如

ex.my = (function(name) {var my_name = name;})('bar'); 

3.我想你是指這個私人方法。

ex = (function() { 
    var foo = 'bar'; 
    return { 
     show: function() {alert(foo);} 
    } 
})(); 

在上面的例子中,只有前者可以訪問foo。

4.no need,$(document).ready()在一切準備就緒時調用,如果您已經加載了ex.js,則初始化完成。

裏面的一切作爲DOM被加載之前的頁面內容被加載

+0

@ 2需要傳遞什麼參數? @ 3如何訪問私有功能? @ 4我不明白你的意思 – Michael