Is this a good structure for my jQuery scripts?
I want to keep my scripts organized in one .js file for all my site (I have a mess right now), something like namespaces and classes in C#...
(function ($) {
//private variables
$.divref = $("#divReference");
//Namespaces
window.MySite = {};
window.MySite.Home = {};
window.MySite.Contact = {};
//Public function / method
window.MySite.Home.Init = function(params){
alert("Init");
MySite.Home.PrivateFunction();
$.divref.click(function(){
alert("click");
});
};
开发者_运维百科 //private function / method
MySite.Home.PrivateFunction = function(){
alert("Private");
};
})(jQuery);
Is this an idiomatic layout in jQuery and JScript?
I'll go ahead and post my comment as an answer, though I'm not 100% it addresses your questions about c# namespaces and their parallels in JavaScript (I'm no c# programmer). You're not actually creating private variables because you're attaching them to the $
Object that will exist after this function finishes. If you want private variables you need to use a closure. Those look something like this:
var myObject = function () {
var innerVariable = 'some private value';
return {
getter: function () {
return innerVariable;
}
}
}()
If you attempt to access myObject.innerVariable
it will return undefined
but if you call myObject.getter()
it will return the value correctly. This concept is one you will want to read up on in JavaScript, and for programming in general. Hope that helps.
This is more how I would implement the pattern you are trying to do:
// MySite.Home Extension
window.MySite =
(function ($, root) {
//private variables
var $divref = $("#divReference");
//private function / method
var privateFunction = function(){
alert("Private");
};
root.Home = {};
// Public variable
root.Home.prop = "Click"
//Public function / method
root.Home.Init = function(params){
alert("Init");
private();
$divref.click(function(){
alert(root.Home.prop);
});
};
return root;
})(jQuery, window.MySite || {} );
// MySite.Contact Extension
window.MySite =
(function ($, root) {
root.Contact = {};
// More stuff for contact
return root;
})(jQuery, window.MySite || {} );
The first change is splitting each "namespace" into its own Module pattern, so private variables wont bleed from namespace to namespace (if you do intend them to be private to the namespace, which would be more C# esque). Second is rather than accessing window.MySite
, pass in the object that you want to extend (in this case I'm calling it root
). This will give you some flexibility.
Your private methods weren't really private. To make a private method, you just want to make a function var that it bound in the closure, but not assigned to a property on the externally visible object. Lastly, you probably don't want to use $.somegarbage
. Like mentioned in a comment, you are adding a property to the $
object, which will still be there when the closure is done. If you wanted something close, I would just use $somegarbage
which some people seem to like to do, but any variable name will work for private variables, just as long as the variable is bound in the closures scope (not somewhere else)
You are on the right track...
you might want to read up on the Module pattern (more) and closures in javascript to prevent polluting the global namespace.
精彩评论