2012-04-17 104 views
5

我永遠忽略了javascript。幾年前我開始使用jQuery,所以我可以通過。但是當我開始做TDD的時候,我決定昨天真的潛入javascript(並且可能之後可能還有coffeescript)。如何跨多個文件跨越javascript命名空間?

在我的ASP.NET Web窗體應用程序中,我有很多頁面,目前這些頁面中的大多數沒有大量的JavaScript。我正在改變這個過程。我使用Jasmine和Chutzpah來創建我的測試。

我正在與我的測試一起移動,並按預期失敗。但後來我想創建一個命名空間,所以我不會在全球空間中踐踏。

看完這篇文章: http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/

我決定嘗試使用來自自執行匿名函數的模式:第2部分的文章(公共&私人)部分。它似乎具有最大的靈活性,似乎很好地封裝了事物。

我有一個名爲/ Scripts的文件夾。在那個文件夾下有一些我使用的框架,比如jQuery,jasmine,(twitter)bootstrap和modernizr。我還有一個名爲/ Site的子文件夾,我在該頁面基於多個文件將我的代碼放入網站。 (product.js,billing.js等)

Under/Scripts/Site我添加了一個子文件夾到/測試(或規格)有文件(product_test.js,billing_tests.js等)。

沒有命名空間,一切都很好。我有一個utility.js文件,我用padLeft輔助函數創建。然後,我在另一個.js文件中使用了全局padLeft。我的測試都很有效,我很高興。於是我決定找出命名空間和改變了我的腳本/網站/ utility.js的樣子:

(function (myns, $, undefined) { 
    //private property 
    var isSomething = true; 

    //public property 
    myns.something = "something"; 

    //public method 
    myns.padLeft = function (str, len, pad) { 
     str = Array(len + 1 - str.length).join(pad) + str; 

     return str; 
    }; 


    //check to see if myns exists in global space 
    //if not, assign it a new Object Literal 
}(window.myns= window.myns|| {}, jQuery)); 

然後在我的腳本/網站/測試/ utility_test.js我

/// <reference path="../utility.js" /> 

describe("Namespace myns with public property something", function() { 
    it("Should Equal 'something'", function() { 
     expect(myns.something).toEqual('something'); 
    }); 
}); 

通過這個非常簡單的測試,我期待myns.something返回字符串值'something'。

它沒有。它回來undefined

那麼,如何跨多個文件使用JavaScript命名空間?

對不起,很長的介紹,但我想它可能有助於解釋爲什麼我這樣做。我也把所有這些放在了一起,因爲我很樂意聽到關於這種設置完全錯誤或部分錯誤或其他方面的想法。

感謝您花時間閱讀此問題。

更新:已解決 謝謝大家的幫助。最大的幫助來自評論者T.J.克勞德。我不知道jsbin工具的存在,並確信我將上面提供的代碼放入工具中,結果是正確的,我知道我的環境中必須有某些東西在關閉。

接受答案中的鏈接也幫了我很多。在看到語法和邏輯是一致的並且工作之後,我只需確定關於我的設置的內容。我很尷尬地說,這是我傳遞jQuery,但在我的測試工具,我試圖讓這個工作,我實際上並沒有使用jQuery。這意味着該模塊並沒有真正被加載 - 所以myns從未設置過。

謝謝大家。希望這可能對未來某個人有所幫助。如果你使用上面,請確保你包含jQuery對象。另一種選擇是不傳入jQuery並從參數列表中刪除$。

+2

你已經顯示應該工作,提供'utility.js'和'utility_test.js'包括在內,並按照這個順序。例如:http://jsbin.com/idofog – 2012-04-17 13:02:46

+0

感謝您長期的介紹,它幫助我們弄清楚你想要什麼:-) – Philipp 2012-04-17 13:04:16

+0

@ T.J.Crowder謝謝。該垃圾箱的作品,但我不明白爲什麼它在我的環境中是不同的。我不知道jsbin,所以也謝謝你!我將在該沙箱中嘗試幾件事情。 – 2012-04-17 13:39:35

回答

0

Javascript沒有命名空間,我想你有變量作用域的麻煩,這與其他語言類似,你所談論的是對象。你可以使用

window.myns.something 

第一功能已經加入你的對象到窗口對象,窗口對象是可訪問的任何地方。

+0

使用像這樣的嵌套屬性是在Javascript中模擬名稱空間的常用方法。 – Alnitak 2012-04-17 13:07:19

+0

我知道,但正如你所說,它是「模擬」命名空間。名稱空間有很大的不同,例如在.NET中,但它類似於.NET中的對象(除了在運行時更改界面) – Philipp 2012-04-17 13:09:21

+0

@PhilippMehrwald謝謝。我應該更清楚地說明「模擬命名空間」。在我嘗試避免使用window.myns.something後,我使用了這種模式。即使將其更改爲我的測試文件中的失敗。所以我必須有其他的錯誤。謝謝! – 2012-04-17 13:44:21

1

嘗試把你的名字空間聲明中的函數調用的外部:

myns = window.myns || {}; 
(function(myns, $, undefined) { 
    ... 
}(myns, jQuery)); 

您現有的語法似乎是完全有效的,但打破了線路輸出可以幫助找出與您的變量範圍走錯了。

+0

謝謝,我試過了,但得到了相同的結果。看起來我有其他東西搞砸了。挖掘它... – 2012-04-17 13:44:49