如何跨多个文件跨越javascript命名空间?

时间:2012-04-17 12:56:49

标签: javascript unit-testing javascript-namespaces

我永远忽略了javascript。几年前我开始使用jQuery,所以我可以顺利通过。但是,随着我开始更多地使用TDD,我昨天决定真正深入了解javascript(之后可能还有coffeescript)。

在我的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等)

在/ Scripts / Site下我向/ Tests(或Specs)添加了一个子文件夹,其中包含文件(product_test.js,billing_tests.js等)。

没有名称空间,一切都很好。我有一个用 padLeft 辅助函数创建的utility.js文件。然后我在另一个.js文件中使用了全局padLeft。我的测试都奏效了,我很高兴。然后我决定找出命名空间并将我的Scripts / Site / 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并从param列表中删除$。

2 个答案:

答案 0 :(得分:1)

尝试将您的名称空间声明放在函数调用之外:

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

您现有的语法似乎完全有效,但打破这一行可能有助于弄清楚您的变量范围出了什么问题。

答案 1 :(得分:0)

Javascript没有名称空间,我猜你有可变范围的麻烦,这与其他语言类似,你所说的是对象。你可以用

window.myns.something

第一个函数已经将对象添加到窗口对象中,窗口对象可以从任何地方访问。