Best way to organize a javascript application - javascript

I have been trying out some different ways to organize my code in my javascript applications and i wonder which one is the most appropriate.
First example:
var Application = {
init: function() {
//Some code
Calculate();
},
Calculate: function() {
//Some code
}
};
Second example:
(function() {
function init() {
//Some code
Calculate();
}
function Calculate() {
//Some code
}
})();
Third example:
(function() {
var init = function() {
//Some code
Calculate();
};
var Calculate = function() {
//Some code
};
})();
Or is it some other way that is preferred? I get very confused over this. Thanks in advance!

The answer is, without question, "it depends." How big is your application? Do you need all of the modules all of the time? How scalable and reusable does your app need to be? These are not JavaScript questions specifically, but rather "architectural" questions, and while learning JavaScript basics is relatively easy, it takes a lot of years to learn to be a good architect in software development. (though it is excellent that you are asking these questions.)
I would encourage you to dive into programming patterns. Learning patterns is learning to structure an application in the right way, depending on the given application.
I can say that a combination of your first example and your second example are a good place to start (an instantly invoked function expression wrapping and returning an object literal). This gives a degree of private scope via closure, and is called the Module Pattern. You will see this pattern used to some degree in almost all major JS applications and libraries because of its versatility and elegance.
To learn more about JavaScript patterns, I highly recommend Addy Osmani's "Learning JavaScript Design Patterns." You can read it for free, here: http://addyosmani.com/resources/essentialjsdesignpatterns/book/

Related

One javascript file kills all the others. Ways to avoid this?

I will not add any code in here. Just working on a project and not only this time, but frequently one javascript file kills the others, so I ussually in this situation looked for similar solution (lets say a different slider and etc.)
But are there any more ways to wrap up some how a javascript file that it wont interfere with the others?
Please provide more details of what exactly you mean - but I have a feeling.
Use namespaces.
If you're using a collective of different libraries it could happen that libraries have the same global name, if you're not using namespaces.
Example how collisions usually occur:
function dontdothis() {
alert("Foo");
}
function dontdothis() {
alert("Bar");
}
dontdothis();
Example how to avoid those collisions:
var myownspace={};
myownspace.dothis=function() {
alert("Foo");
}
function dothis() {
alert("Bar");
}
myownspace.dothis();
In general, each desecrate chuck of JavaScript should be wrapped in a closure with an API that is exposed to the wide world through a single global (which has a non-generic name, so YAHOO is reasonable as it is unlikely to be used by something else, while $ is awful).
This is known as namespacing
If I understood your question correctly, your solution is namespaces.
var APP = {};
APP.namespace = function(sNamespace) {
if ("undefined" == typeof APP[sNamespace]) {
APP[sNamespace] = {};
}
}
Usage:
APP.namespace("profile");
APP.profile.AskQuestionDialog = function(oConfigs) { ... }
DOM tree:
-window
-APP
-profile
And you should define you namespace in beginning of each file using APP.namespace()

Javascript and jQuery file structure

I have created a sizable application javascript and jQuery. However my file structure is getting a bit messy!
At the moment I have one large JS file with a if ($('#myDiv').length > 0) { test at the top to only execute the code on the correct page, is this good practice?
There is also a mixture of plain JS functions and jQuery extensions in the same file e.g $.fn.myFunction = function(e) {.
I also have a few bits of code that look like this:
function Product() {
this.sku = '';
this.name = '';
this.price = '';
}
var myProduct = new Product;
Basket = new Object;
My question is for pointers on good practice regarding javascript and jQuery projects.
The code if ($('#myDiv').length > 0) { is not good practice. Instead, make your page specific JS as functions and execute them in the corresponding page . Like this:
var T01 = function(){
// JS specific to Template 01
};
var T02 = function(){
// JS specific to Template 02
};
HTML head of Template 01:
<script type="text/javascript"> $(T01); </script>
Consistency is the golden rule.
You can discuss design patterns back and forth, but if you want to have easily maintainable code where new people can come in and get an overview fairly quickly, the most important part, whatever design patterns you chose, is to have a consistent code base.
It is also the hardest thing to do - keeping your codebase clean and consistent is probably the hardest thing you can do as a programmer, and especially as a team.
Of course the first tip I can give you is to separate the jQuery extensions in their own source files. You can always serve everything together with a minification tool, so you should not worry about performance.
About the code youo mention, it could be simplified to
var Product = {
sku: '',
name: '',
price: ''
}
var myProduct = objectCopy(Product);
var Basket = {};
provided you write a simple objectCopy function which loops through the object own properties and just copies them to a new object (you can make a shallow or a deep copy, according to your needs).
Finally, if you think your code is starting to get messy, you may want to learn some patterns to organize JS code, like the module pattern. Alternatively, if you are familiar with doing this on the backend, you may want to organize your application following the MVC pattern. personal advertisement - I have written myself a tiny library which helps organize your code in this fashion. There are also many other libraries for the same task, often adding other functionality as well.
If you follow the MVC pattern, your page will actually correspond to some action in some controller, and you could just start it with a call like
<script>someController.someAction()</script>
in the head of your document, hence removing the need for the manual check for #myDiv. If you use my library MCV, it will be enough to declare your body like
<body class="mcv:controller/action">
and start the application with
$(document).ready(function() {
mcv.autostart();
});
Yes it's good practice to put as much of your code into a seperate JS file as this could then be compressed before transmission and hence speed up download time. However no you should not have code that looks like
if ($('#myDiv').length > 0) {
on every page. Split your JS code up into manageable functions and call those as-and-when you need to.
I don't see a problem with mixing JS and jQuery functions up in the same file.

Interface Segregation Principle in jQuery

Anyone able to give a good illustration of how this works in jQuery?
Specifically with regards to the answer from here.
It sounds the same as Single Responsibility Principle (SRP) for OOP? How is it different?
I feel more comfortable with answering my own question now.
With Single Responsibility Principle, I'm thinking mainly of objects created like in a game. That object should be responsible only for itself, in terms of internal functions/methods.
As for Interface Segregation, I'm thinking more of avoiding anonymous function calls, and segregating a large chunk of code... to different named calls. This was well explained by Paul Irish in jQuery Anti-Patterns for performance.
Instead of anonymous functions bound everywhere like
$(function() {
//do stuff related to setup menu
//add facebook, twitter widgets
//more anonymous actions....
}):
Segregation into a well defined interface might look something like the below:
var homepage = (function() {
function setupMenu() {
//do stuff related to setup menu
}
function setupSocial() {
//add facebook, twitter widgets
}
return {
setupMenu:setupMenu,
setupSocial:setupSocial
}
})();
$(function() {
homepage.setupMenu();
homepage.setupSocial();
})

How to use javascript namespaces correctly in a View / PartialView

i've been playing with MVC for a while now, but since the project i'm on is starting to get wind in its sails more and more people are added to it. Since i'm in charge of hacking around to find out some "best practice", i'm especially wary about the possible misuses of javascript and would like to find out what would be the best way to have our views and partial views play nicely with javascript.
For the moment, we're having code that looks like this (only simplified for example's sake)
<script type="text/javascript">
function DisableInputsForSubmit() {
if ($('#IsDisabled').is(':checked')) {
$('#Parameters :input').attr('disabled', true);
} else {
$('#Parameters :input').removeAttr('disabled');
}
}
</script>
<%=Html.SubmitButton("submit", Html.ResourceText("submit"), New With {.class = "button", .onclick = "DisableInputsForSubmit(); if ($('#EditParameters').validate().form()) {SetContentArea(GetHtmlDisplay('SaveParameters', 'Area', 'Controller'), $('#Parameters').serialize());} return false;"})%><%=Html.ResourceIcon("Save")%>
Here, we're saving a form and posting it to the server, but we disable inputs we don't want to validate if a checkbox is checked.
a bit of context
Please ignore the Html.Resource* bits, it's the resource management
helpers
The SetContentArea method wraps ajax calls, and GetHtmlDisplay
resolves url regarding an area,
controller and action
We've got combres installed that takes care of compressing, minifying
and serving third-parties libraries and what i've clearly identified as reusable javascript
My problem is that if somebody else defines a function DisableInputsForSubmit at another level (let's say the master page, or in another javascript file), problems may arise.
Lots of videos on the web (Resig on the design of jQuery, or Douglas Crockford for his talk at Google about the good parts of javascript) talk about using the namespaces in your libraries/frameworks.
So far so good, but in this case, it looks a bit overkill. What is the recommended way to go? Should i:
Create a whole framework inside a namespace, and reference it globally in the application? Looks like a lot of work for something so tiny as this method
Create a skeleton framework, and use local javascript in my views/partials, eventually promoting parts of the inline javascript to framework status, depending on the usage we have? In this case, how can i cleanly isolate the inline javascript from other views/partials?
Don't worry and rely on UI testing to catch the problem if it ever happens?
As a matter of fact, i think that even the JS code i've written that is in a separate file will benefit from your answers :)
As a matter of safety/best practice, you should always use the module pattern. If you also use event handlers rather than shoving javascript into the onclick attribute, you don't have to worry about naming conflicts and your js is easier to read:
<script type="text/javascript">
(function() {
// your button selector may be different
$("input[type='submit'].button").click(function(ev) {
DisableInputsForSubmit();
if ($('#EditParameters').validate().form()) {
SetContentArea(GetHtmlDisplay('SaveParameters', 'Area','Controller'), $('#Parameters').serialize());
}
ev.preventDefault();
});
function DisableInputsForSubmit() {
if ($('#IsDisabled').is(':checked')) {
$('#Parameters :input').attr('disabled', true);
} else {
$('#Parameters :input').removeAttr('disabled');
}
}
})();
</script>
This is trivially easy to extract into an external file if you decide to.
Edit in response to comment:
To make a function re-usable, I would just use a namespace, yes. Something like this:
(function() {
MyNS = MyNS || {};
MyNS.DisableInputsForSubmit = function() {
//yada yada
}
})();

Namespacing technique in JavaScript, recommended? performant? issues to be aware of?

In a project I am working on I am structuring my code as follows
MyLib = {
AField:0,
ASubNamespace:{
AnotherField:"value",
AClass:function(param) {
this.classField = param;
this.classFunction = function(){
// stuff
}
}
},
AnotherClass:function(param) {
this.classField = param;
this.classFunction = function(){
// stuff
}
}
}
and so on like that to do stuff like:
var anInstance = new MyLib.ASubNamespace.AClass("A parameter.");
Is this the right way to go about achieving namespacing? Are there performance hits, and if so, how drastic? Do performance degradations stack as I nest deeper? Are there any other issues I should be aware of when using this structure?
I care about every little bit of performance because it's a library for realtime graphics, so I'm taking any overhead very seriously.
I suggest namespacing is a critical part of writing maintainable JavaScript - especially if you work with a team of developers.
Performance issues related to namespacing should be minimal if you compress/minimize your code on the way to production.
Here is an SO discussion of alternative ways to use namespaces.
When you structure your code as a big giant object-property hierarchy, you sometimes have issues where MyNamespaceObj.prop1 isn't available to MyNamespaceObj.prop2 yet. And then there's the fact that you often end up typing fully qualified names a lot throughout the code.
I'm starting to find I prefer doing something like this:
MyNamespaceObj = (function () {
// lots of code/definitions that have local scope
var internallyDefinedItem1 = function (n) { /* ... */ }
var internallyDefinedItem2 = {
foo: internallyDefinedItem1(532),
bar: totallyPrivateNeverExportedFunction(17)
}
var totallyPrivateNeverExportedVar = 'blahblahblah';
function totallyPrivateNeverExportedFunction (x) {
/* ... */
}
return {
exportedItem1: internallyDefinedItem1,
exportedItem2: internallyDefinedItem2,
...
}
})();
Namespacing your JavaScript is critical to avoid potential conflicts and overwrites. This is specially true when your JS will land up in foreign environments where external JS can also reside.
With that said, there is a performance hit because of namespacing, simply because the interpreter now has to follow a longer chain to access the required function/property.
For example, something like
var myProperty;
is accessed a little faster as compared to :
myNameSpace.module1.myProperty;
I think the difference in speed is not much unless you namespace extremely deeply and the advantage of avoiding potential conflicts is a big plus of namespacing.
But still, it is always good to keep this issue in mind.

Categories

Resources