5

我永远忽略了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 ));

然后在我的 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.something 以字符串值“something”返回。

它没有。它回来了undefined

那么,如何跨多个文件使用 javascript 命名空间?

很抱歉介绍了这么长,但我认为这可能有助于解释我这样做的原因。我也提出了所有这些,因为我愿意听取有关此设置如何完全错误或部分错误或其他任何想法的想法。

感谢您花时间阅读这个问题。

更新:已解决 谢谢大家的帮助。最大的帮助来自评论者@TJ Crowder。我不知道 jsbin 工具的存在,在确信我将上面的代码放入工具中并且结果正确之后,我知道我的环境中必须有一些东西。

已接受答案中的链接也对我有很大帮助。在看到语法和逻辑是一致的并且可以正常工作后,我只需要确定我的设置有什么问题。我很尴尬地说是我传入了 jQuery,但是在我试图让它工作的测试工具中,我实际上并没有使用 jQuery。这意味着该模块实际上并没有被加载 - 所以 myns 从未设置过。

感谢大家。希望这可能对将来的某人有所帮助。如果您使用上述方法,请确保包含 jQuery 对象。另一个选项是不传入 jQuery 并从参数列表中删除 $。

4

2 回答 2

1

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

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

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

于 2012-04-17T13:04:18.543 回答
0

Javascript没有命名空间,我猜你在变量范围方面有问题,这与其他语言类似,你所说的是对象。你可以使用

window.myns.something

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

于 2012-04-17T13:02:37.373 回答