views:

93

answers:

5

Is the following method wrong way of declaring namespace in Javascript? It is from the book I'm reading and doesn't seem to work in my code.

<script type="text/javascript">
var mynamespace = {};

if(Drupal.jsEnabled){       
    $(document).ready(mynamespace.init);    
}

mynamespace.init = function() {
    $("#mybutton").bind("click",function(){     
        alert('hello');
    });
}

</script>
A: 

What strikes me as odd, at least working mostly in C#, is that a namespace should not directly contain code logic. In C# it can't, that is what classes are for. So for me, having an init function on a namespace is a contradiction.

jarrett
That's because namespaces don't exist in JavaScript - it's just a way to package functionality to avoid scope collisions. "Namespace" is just a borrowed term.
Peter Bailey
I understand its not enforceable, but namespace still seems like the wrong term to borrow if you are adding an init function to it. Just my opinion.
jarrett
+1  A: 

What seems to be going wrong here is that the mynamespace.init function isn't defined at the time you are hooking it up to $(document).ready.

This should work as expected:

<script type="text/javascript">
var mynamespace = {};

mynamespace.init = function() {
    $("#mybutton").bind("click",function(){     
        alert('hello');
    });
}

if(Drupal.jsEnabled){       
    $(document).ready(mynamespace.init);    
}

</script>

You may also consider forming it like this, as it is easier to understand (at least to me anyhow)

<script type="text/javascript">
var mynamespace = {
    init : function() {
        $("#mybutton").bind("click",function(){     
            alert('hello');
        })
};

if(Drupal.jsEnabled){       
    $(document).ready(mynamespace.init);    
}

</script>
James Maroney
Thanks a lot. It works. And I also agree with you on the snippet you've given;it's looks cleaner. thanks for that.
Andrew
+2  A: 

It looks like your code is dependent on jQuery. Make sure that is loaded before you run this script. Also, define your function before it gets called. Try this:

var mynamespace = {};

mynamespace.init = function() {
    $("#mybutton").bind("click",function(){     
        alert('hello');
    });
}

if(Drupal.jsEnabled){       
    $(document).ready(mynamespace.init);    
}
Jeff Fohl
What jarrett says below is true. JavaScript doesn't have a true namespace methodology like other languages. You just name your classes in an intelligent way when you define them.By the way - the above code doesn't define a class per se, but is rather just a simple object instance.
Jeff Fohl
It never occurred to me order of code would prevent it from working. Thanks a lot.
Andrew
+1  A: 

Be careful using $(document).ready(mynamespace.init);. When executed in this way, this is no longer a reference to mynamespace, normally it would be equal to window, but jQuery do some call magic in the background to set it equal to document. It won't hurt you in this instance, but be wary of it in the future.

$(document).ready(function () {
    mynamespace.init();
});

Is how I would do it.

In this case, the reason your code isn't working is that the init method of mynamespace isn't defined at the document $(document).ready(mynamespace.init) is called.

Matt
That's interesting. Thanks.
Andrew
`$(function(){ mynamespace.init(); });` is how I would do it. :-)
David Murdoch
A: 

Yes, you can use object as a namespace. Another way to form a namespace is to use closures:

(function(inner_variable_1, inner_variable_2) {

    // define whatever here, they won't pollute namespace outside this closure

})(outer_variable_1, outer_variable_2);

Popular example is jQuery's noconflict-mode, which enables you to use $ variable in your jQuery code without making $ a global variable, thus leaving the global $ for another use.

jholster