How to span javascript namespace across multiple files?

别等时光非礼了梦想. 提交于 2019-12-21 05:03:07

问题


I have ignored javascript forever. I started using jQuery a few years back so I could get by. But as I've started doing TDD more I decided yesterday to really dive into javascript (and possibly coffeescript after that).

In my ASP.NET Web Forms application I have many pages and currently most of those pages do not have a ton of javascript. I'm in the process of changing that. I'm using Jasmine with Chutzpah to create my tests.

I was moving along with my tests passing and failing as expected. But then I wanted to create a namespace so I wouldn't be trampling all over global space.

After reading this article: http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/

I decided to try and use the pattern from the Self-Executing Anonymous Function: Part 2 (Public & Private) section of the article. It appears to have the most flexibility and appears to encapsulate things very well.

I have a folder called /Scripts. Under that folder are some of the frameworks I'm using like jQuery, jasmine, (twitter) bootstrap and modernizr. I also have a subfolder called /Site where I am putting my code for the site in multiple files based on the page. (product.js, billing.js, etc.)

Under /Scripts/Site I added a subfolder to /Tests (or Specs) that have the files (product_test.js, billing_tests.js, etc.).

Without having namespaces everything is fine. I have a utility.js file I created with a padLeft helper function. I then used that global padLeft in another .js file. My tests all worked and I was happy. I then decided to figure out the namespace and changed my Scripts/Site/utility.js to look like:

(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 ));

Then in my Scripts/Site/Tests/utility_test.js I have

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

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

With this extremely simple test I was expecting myns.something to come back with the string value of 'something'.

It doesn't. It comes back undefined.

So, how do I to use javascript namespace across multiple files?

Sorry for the long introduction, but I figured it may help explain the why of me doing it this way. I also put all of this because I'm open to hearing ideas about how this setup is totally wrong or partially wrong or whatever.

Thanks for taking the time to read this question.

UPDATE: SOLVED Thank you all for your help. The most help came from the commenter @T.J. Crowder. I didn't know the jsbin tool existed and after being convinced that the code I put above was put into the tool and the results were right I knew something had to be off in my environment.

The link in the accepted answer also helped me out a lot. After seeing that the syntax and logic was consistent and working I just had to determine what was off about my setup. I'm embarrassed to say it was me passing in jQuery but in my test harness where I was trying to get this to work I wasn't actually using jQuery. This meant the module wasn't actually being loaded - so myns was never set.

Thanks everyone. Hopefully this may be helpful to someone in the future. If you use the above make sure you include the jQuery object. The other option is to not pass in jQuery and remove the $ from the param list.


回答1:


Try putting your name space declaration outside of the function call:

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

Your existing syntax appears to be completely valid, but breaking that line out may help figure out what's going wrong with your variable scope.




回答2:


Javascript does not have namespaces, i guess you have troubles with variable scopes and this is similar to other languages, what you are talking about are objects. You could use

window.myns.something

The first function is already adding your object to the window object, and the window object is accessible from anywhere.



来源:https://stackoverflow.com/questions/10191724/how-to-span-javascript-namespace-across-multiple-files

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!