如何跨多个文件跨javascript命名空间?
我永远忽略了javascript。几年前我开始使用jQuery,这样我就可以过日子了。但随着我开始更多地使用TDD,我昨天决定真正深入研究javascript(之后可能还有coffeescript) 在我的ASP.NET Web表单应用程序中,我有许多页面,而目前这些页面中的大多数都没有大量javascript。我正在改变这一点。我正在用茉莉花和Chutzpah来创建我的测试 我在继续我的测试,正如预期的那样通过和失败。但后来我想创建一个名称空间,这样我就不会践踏整个全局空间 读完这篇文章后: 我决定尝试使用本文第2部分(公共和私有)中的自动执行匿名函数中的模式。它似乎具有最大的灵活性,并且似乎能够很好地封装事物 我有一个名为/Scripts的文件夹。在这个文件夹下是我正在使用的一些框架,比如jQuery、jasmine、(twitter)bootstrap和Modernizer。我还有一个名为/Site的子文件夹,在此文件夹中,我将根据页面将网站代码放入多个文件中。(product.js、billing.js等) 在/Scripts/Site下,我向/Tests(或Specs)添加了一个子文件夹,其中包含文件(product_test.js、billing_Tests.js等) 没有名称空间,一切都很好。我有一个使用padLeft helper函数创建的utility.js文件。然后我在另一个.js文件中使用了这个全局padLeft。我的测试都成功了,我很高兴。然后,我决定找出名称空间,并将脚本/Site/utility.js更改为:如何跨多个文件跨javascript命名空间?,javascript,unit-testing,javascript-namespaces,Javascript,Unit Testing,Javascript Namespaces,我永远忽略了javascript。几年前我开始使用jQuery,这样我就可以过日子了。但随着我开始更多地使用TDD,我昨天决定真正深入研究javascript(之后可能还有coffeescript) 在我的ASP.NET Web表单应用程序中,我有许多页面,而目前这些页面中的大多数都没有大量javascript。我正在改变这一点。我正在用茉莉花和Chutzpah来创建我的测试 我在继续我的测试,正如预期的那样通过和失败。但后来我想创建一个名称空间,这样我就不会践踏整个全局空间 读完这篇文章后:
(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 ));
然后在我的Scripts/Site/Tests/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”,函数(){
它(“应该等于‘某物’”,函数(){
期望(某物);
});
});
通过这个非常简单的测试,我希望myns.something返回字符串值'something'
没有。它没有定义
那么,如何跨多个文件使用javascript名称空间?
抱歉这么长时间的介绍,但我想这可能有助于解释我为什么要这样做。我也把所有这些都放在这里,因为我乐于听到关于这个设置是完全错误还是部分错误的想法
感谢您抽出时间阅读此问题
更新:已解决
谢谢大家的帮助。最大的帮助来自评论人T.J.Crowder。我不知道jsbin工具的存在,在确信我在上面输入的代码被放入该工具并且结果是正确的之后,我知道我的环境中必须关闭一些东西
接受答案中的链接也帮了我很多忙。在看到语法和逻辑是一致的并且工作正常之后,我只需要确定我的设置有什么问题。我很难为情地说是我通过了jQuery,但在我的测试工具中,我试图让它发挥作用,但实际上并没有使用jQuery。这意味着模块实际上没有被加载,因此从未设置myns
谢谢大家。希望这对将来的人有所帮助。如果使用上述方法,请确保包含jQuery对象。另一个选项是不传入jQuery并从参数列表中删除$ Javascript没有名称空间,我想您在变量作用域方面有问题,这与其他语言类似,您所说的是对象。你可以用
window.myns.something
第一个函数已将您的对象添加到窗口对象,并且可以从任何位置访问该窗口对象。尝试将您的名称空间声明放在函数调用之外:
myns = window.myns || {};
(function(myns, $, undefined) {
...
}(myns, jQuery));
您现有的语法似乎完全有效,但划掉这一行可能有助于找出您的变量作用域出了什么问题。使用这样的嵌套属性是在Javascript中模拟名称空间的常见方法。我知道,但正如您所说,这是“模拟”名称空间。名称空间(例如.NET中的名称空间)存在巨大差异,但它与.NET中的对象类似(除了在运行时更改接口)@PhilippMehrwald,谢谢。我应该更清楚地说明“模拟名称空间”。对于我所追求的模式,我试图避免使用window.myns.something。甚至在我的测试文件中将其更改为那样也失败了。所以我一定是出了什么问题。谢谢myns最初定义在哪里?@PhilippMehrwald它当前在第一个代码块底部的Script\utilities.js中定义:window.myns=window.myns | |{},谢谢,我尝试过了,但得到了相同的结果。看来我还有别的事搞砸了。深入研究一下……这里有一篇关于模块模式(您在这里使用的)的非常好的文章,介绍了如何跨文件实现它:如果同时包含
utility.js
和utility\u test.js
,并且按此顺序,您所展示的应该可以工作。示例:感谢您的长时间介绍,它帮助我们了解您想要什么:-)@T.J.Crowder谢谢。那个垃圾箱可以工作,但我不明白为什么它在我的环境中是不同的。我不知道jsbin,所以也谢谢你!我要在沙箱里试几样东西。