2010-06-13 109 views
9

在JavaScript中聲明全局範圍內的變量是一件壞事。所以我傾向於使用的代碼包含命名空間JavaScript。分享JavaScript庫的名稱空間或使用您自己的名稱空間?

似乎有采取這種兩種不同的方法 -

  1. 將您的應用程序特定功能的圖書館命名空間例如$.myCarouselfunction
  2. 創建自己的名稱空間例如MyApplication.myCarouselFunction

我想知道是否有更好的解決方案,或者他們是否傾向於在利弊方面接近。

我個人決定不去圖書館的原因是分離/隔離/缺乏與圖書館代碼和可能共享該名稱空間的潛在插件的衝突。有沒有更多的這一點,我不考慮?

回答

1

我傾向於更喜歡自己添加自定義代碼到庫中。最大的原因是,使用語義在內置代碼和我的自定義代碼中保持一致。這就是說,我不能真正想到這種方法的任何技術優勢或劣勢。我認爲你對衝突的擔憂是有效的,雖然可能不太可能(如果最終出現與你的一個自定義函數衝突的組件/模塊,很可能是因爲你正在用別人的代碼替換你的代碼)。

1

正確的選擇取決於您的目標環境。你在兩個命名空間之間進行選擇,這兩個命名空間可能會變得雜亂無章。如果您認爲在庫命名空間中遇到衝突的可能性更大,則應使用窗口命名空間。如果您認爲窗口命名空間更可能混亂,請選擇庫命名空間。

無論哪種情況,您通常只應創建一個「全局」名稱。換句話說,如果要將函數放入庫的名稱空間中,最好不要將其命名爲$ .myFn。將其命名爲$ .yaya3.myFn,然後在您調用myFn多次的任何上下文中緩存本地引用。

參考你的功能是通過它生活在作爲參數傳遞給一個匿名函數命名空間的一個最佳實踐:

(function (yaya3) { 
var myFn = yaya3.myFn; 
myFn("frobnard!"); 
}(window.yaya3)); // you could instead pass $.yaya3 or YUI.namespace("yaya3") here 

這使得如果你發現你需要移動更容易到不同的命名空間。

+0

我不我真的看不到這會給你帶來什麼。首先,作爲一個圖書館維護者,除非它不會向後兼容,否則我不會創建yaya4,在這種情況下,您必須審覈代碼;其次,如果您確實想要更改爲yaya4,如果您只是將所有對yaya3的引用替換爲yaya4,那麼這些代碼是不是更具可讀性? – nas 2010-07-03 08:45:05

16

我認爲選擇這種東西最重要的是語義

您的函數/類是擴展還是依賴於庫特定的功能?把它放在庫名字空間中。

是你的函數/類庫獨立嗎?在這種情況下,最好將它放在自定義命名空間中。這樣可以在原來使用它的庫之外重用代碼。

+0

我同意,但請記住,通過使用名稱空間可以避免潛在的名稱衝突,特別是在庫更新之後,尤其是在可以重新定義變量的情況下,所有內容都會像沒有任何事情發生一樣繼續。 – user347594 2010-07-07 15:15:23

+0

+1這個答案對我來說是確定的贏家。 – Fenton 2010-07-07 16:50:17

2

如果您曾嘗試使用相同的命名空間引入多個庫,那麼可能會發生碰撞的可能性會很驚人,並且可能會令人非常沮喪,因爲這些類型的錯誤常常令人驚訝並且很難調試方式。我認爲你對衝突的直覺是正確的,關於是定義你自己的命名空間還是重用別人的最重要的考慮是尊重命名空間的所有權。這意味着,除非您與維護另一個命名空間的人員聯繫,並且他們知道您在做什麼,否則使用您自己的命名空間是一個好主意。

如果您決定忽略命名空間所有權的建議並在現有名稱空間(針對語義或其他)定義API,則需要考慮的一件事是使用導出函數來檢測錯誤。基本上,你可以先定義你自己的命名空間的東西,然後將其導出到目標命名空間,沿着線:

MyApplication.exportName = function(objToExportTo, name, obj) { 
    if (objToExportTo[name] === undefined) { 
    objToExportTo[name] = obj; 
    } else { 
    // Possibly assert! 
    } 
}; 

MyApplication.myCarouselFunction = function() { ... }; 
MyApplication.exportName($, 'myCarouselFunction', MyApplication.myCarouselFunction); 
3

個人而言,我喜歡這種方法:

(function(namespace) { 

function myPrivateFunction(){}; 

namespace.myPublicFunction = function(){}; 

})($); // passing the $ namespace, but if it clutters, 
     // we can change it to something else 
相關問題