JavaScript series, part 1 – WebApp, The beginning
Hello and welcome to my first article about JavaScript WebApplication development. At first I wanted to write this as a private memento, a reminder to myself, but then I decided to share it on my blog so that, hopefully, someone would read this and maybe comment, letting me know whether I’m right or wrong and leaving some notes on how I can improve my techniques. Please feel free to correct my English too if you find any errors.
Cover story: a view from Castello di Montebello (castle of Montebello), Poggio Torriana, Italy. Like the photo, which shows a broad view of the Marecchia Valley, this article should start with a broad view about JavaScript, given by some resources i’ll link below. The castle isn’t shown in the photo (since i’m standing on one of its walls, facing Marecchia Valley), but there’s an interesting legend about a ghost bound to the castle (like there are many legends about JavaScript).
This article is like a prologue to a series of JavaScript articles about WebApp development that will cover many aspects of writing client side code that will scale. You don’t need particular tools to write JavaScript, but I’ll recommend Notepad++ to get started since it’s easy but powerful.
The scope of this article can be summarized in 5 points:
- trace some good resources about learning (or improving) JavaScript skills;
- show some examples of code conventions that I used and helped me to keep my projects tidy and organized;
- give some examples of how I use JSDoc for comments;
- show a particular namespace pattern and some of the advantages that it brings while developing a client side JavaScript web application;
- define a fictional “AClass.js” file where I’ll define a very simple class (prototype).
Before jumping into the world of JavaScript, let me link a couple of resources that helped me a lot:
- Here’s a nice book you can read online for free, “Eloquent JavaScript – second edition”. This book takes you by the hand and guides you to the world of JavaScript, from the beginning to advanced topics.
- If you’re a beginner you should also take a look at this: “MDN – JavaScript guide, Introduction”. MDN is a very useful resource, even for more advanced topics.
- Here’s another book that opened my eyes on a couple of topics I used to underestimate as a beginner: “Secrets of the JavaScript Ninja” by John Resig. This is not for beginners, but if you already work with JavaScript and never heard of “closures” or “prototype model” it’s time to give it a read.
- MDN again, because maybe you skipped it when you read “beginner” in the description, but here are just a couple of advanced topics you should read about:
- A brief document that gets straight to the point, giving you some very good guidelines is this one: “Google JavaScript Style Guide”. I recommend this also to advanced users!
- Always comment your code or you’ll regret it later. I choose to “@use JSDoc”. JSDoc style comments are not just readable and tidy, but give you also the possibility to use documentation generators and other useful tools.
- Last, but not least, stack overflow. A Q&A community of million of programmers, do I have to say more?
Now we can really start, so I will give you some examples showing code conventions I usually apply to my code.
Most of the guidelines I use to follow are taken from Google JavaScript style guide (linked above), so I’ll assume you read that document and leave further explanation to it (in this very moment the document is at rev 2.93). The first example will also show how to define a namespace for a fictional web application and how JSDoc style comments apply to your code. Within next articles I’ll stick to this kind of namespacing pattern as I’ll be introducing new topics.
var AppNamespace = { /** * App's utils namespace * @namespace */ Utils: { /** * This method returns the length of a string object * @param {String} param1, a string. * @return {Number} the length of the string. */ strlen: function (param1) { return param1.length; }, /** * Returns a formatted string representing the date argument in * "YYYY-mm-dd" format. * @param {Date} date, the date to be formatted * @return {String} the date in “YYYY-mm-dd” format */ formatDate: function (date) { return date.getFullYear() + "-" + (1 + date.getMonth()) + "-" + date.getDate(); } }, /** * App's configuration * @namespace */ Config: { /** * A very important application client configuration parameter * @type {bool} */ veryImportantConfigurationParameter: true } };
Maybe you’re thinking: “You aren’t always commenting your code like that, aren’t you?”. Shortly the answer is: I try to always comment my code using JSDoc formalization. Whenever I’m in a rush and cannot write sufficient comments I just plan to do it as soon as I can and possibly I leave single line comments for future use. Code commenting always pays back:
- JSDoc style comments let you use automated tools to easily build code documentation;
- new IDEs expose code hinting and code completion features, also with loosely typed languages as JavaScript, and your comments are shown in the hints;
- You are not a machine and the code you’ll write may be very complex, so comment it! If you want to have a clue of what you did next time you’ll read it;
- Since JavaScript is a loosely typed language, only comments will let you know what kind of input or output are connected to your functions; this may avoid you many language traps and bugs that are difficult to track.
Back to our code, here’s a code snippet that shows how strlen and formatDate utilities can be called:
//get string length of "Hello" var helloLen = AppNamespace.Utils.strlen("Hello"); //helloLen == 5 //format a date object var date = new Date(); //date.toGMTString() == "Mon, 16 Nov 2015 17:18:34 GMT" var dateYmd = AppNamespace.Utils.formatDate(date); //dateYmd == "2015-11-16"
This kind of namespacing pattern may look awkward if you’re not used to it, but this allows you to keep things organized while the webapp codebase keeps growing. If you aren’t keen on namespacing patterns here’s an article that can help: “Essential JavaScript Namespacing Patterns“.
In my experience I also needed to customize UI behavior for different customers and this kind of client side code organization helped me a lot. A quick example may show you how to redefine our strlen method to override its default behavior:
/** * Overrides original AppNamespace.Utils.formatDate to return a "mm/dd/YYYY" * formatted date. * @param {Date} date, the date to be formatted * @return {String} the date in “mm/dd/YYYY” format * @override */ AppNamespace.Utils.formatDate = function (date) { return (1 + date.getMonth()) + "/" + date.getDate() + "/" + date.getFullYear(); };
Now calling formatDate method results in a different behavior:
var dateMDY = AppNamespace.Utils.formatDate(date); //dateMDY == "11/16/2015"
As you might have seen, I usually use Pascal case naming convention for namespaces (“CamelCase” for those who don’t know), while I stick to camel casing for methods and variables.
Now let’s see a couple of examples about prototypes an objects conventions I usually follow. Just as I did before this is example which follows the Google coding style guidelines, so refer to the above linked document for further explanations:
/** * A simple, but rather futile, class definition. * @constructor */ function AClass() { /** * A simple field * @type {int} */ this.aValue = 1; /** * A private field. This can be seen outside the object, so it's not a * real "private" field, but that underscore at the beginning tells the * developer to avoid using it. * @type {bool} */ this._aPrivateField = true; } /** * A simple class method. * @return {int} the value of "aValue" object field. */ AClass.prototype.aMethod = function () { return this.aValue; }; /** * A static class constant (ALL CAPS). * @constant * @type {int} * @default */ AClass.STATIC_CONSTANT = 10;
The following code fragment shows and example of how “AClass” object are instantiated and how you can manipulate them:
//create a new instance of AClass var aObject = new AClass(); //call the "aMethod" method var aVar = aObject.aMethod(); //output aVar value on browser console console.log(aVar); //outputs 1 //add the value of AClass.STATIC_CONSTANT to the "aValue" field aObject.aValue += AClass.STATIC_CONSTANT; //check what happened console.log(aObject.aValue); //outputs 11
Enough for now, in the next article we’ll start writing a very simple single web page application.