JavaScript Notes – 4 (Best Practices)
Posted: February 10th, 2012 | Author: nramakrishnan | Filed under: technical | Tags: javascript | Comments OffIn this blog article I want to discuss on few of the JavaScript best practices that I have gleaned from various people, talks, videos, books. For the sources, see here.
VAR, WHERE?
To start with declaration of variables. The best way to do it is
var oneVariable,
anotherVariable,
oneArray = [],
oneObject = {};
// do your thing
Points to notes -
- Good formatting
- Initialization of arrays and object literals without using new is much cheaper (as scope resolution is not required).
- Do not forget the commas after each of the variables
Staying on the topic of variables, there is a useful-to-know concept of hoisting . The following code segment will elucidate the idea-
var foo = 1;
function bar() {
if (!foo) {
var foo = 10;
}
alert(foo);
}
bar();
Can you guess the output? Click show source below for answer and explanation.
/* the code above re-written to explain
* how the interpreter sees it
*/
var foo = 1;
function bar(){
var foo; // the declaration of foo is hoisted to the top of the scope and undefined
if(!foo){ // foo is undefined now, this foo not the global variable
foo = 10; // set the value of the local variable foo
}
alert(foo); // alert foo, the local foo
}
bar(); // alerts 10
So that is the idea of hoisting explained simplistically. The lesson is to have all your var statements together at the top of the function to avoid such issues. There is something similar that happens with functions too, you can read more about it in Ben Cherry’s article. Long story short, you would want to define your functions before using them.
Do remember that JavaScript has function-level scope, not block level scope . You can create block level scope using anonymous, immediately-executing functions. I will do a more detailed blog post on JavaScript scoping and chaining later.
ARRAYS, LOOPS, YEAH TOGETHER
var a = []; console.log(typeof a); // "object" Arrays are objects, not arrays. console.lo(a.length); // 0 a[10] = "nadu"; console.log(a.length); //11 a["another_element"] = "another nadu"; console.log(a.another_element); // another_nadu console.log(a.length); // 11 (still)
This means that arrays are slow, because they are effectively represented as objects. So, the easiest way to improve performance is to NOT do this
var i,
elements = document.getElementsByTagName("div"); // a huge array
for(i=0; i<elements.length; i++){
//add a class to the div
// do something else
}
What is wrong? Well, in each iteration, the length of the elements array is calculated instead just cache the length in a variable and compare it with the loop variable. No big shakes at all right? Well do remember to do this for big arrays!
var i,
elements = document.getElementsByTagName("div"), // a huge array
l = elements.length;
for(i=0; i<l; i++){
//add a class to the div
// do something else
}
DOOM DOM
Few rules for manipulation of the DOM gleaned from this talk.
USE FRAGMENTS TO APPEND NEW ELEMENTS
Assume, you have a container div element and you want to create the child div elements after getting some JSON data from an external server. For appending the child elements,
var i,
cDiv = document.getElementsById("container-div"),
l = jsonResponse.length ;
for(i=0; i<l; i++){
var newChild = document.createElement("div");
newChild.innerHTML = jsonResponse[i];
cDiv.appendChild(newChild);
}
The problem here is that if there are 100 children divs that are going to be created, then the live DOM will be modified 100 times for appending each child div and the performance takes a hit. Instead, the better method is to create a document fragment, append your nodes to the fragment and then attach the fragment to the live DOM.
var i,
cDiv = document.getElementsById("container-div"),
frag = document.createDocumentFragment(),
l = jsonResponse.length ;
for(i=0; i<l; i++){
var newChild = document.createElement("div");
newChild.innerHTML = jsonResponse[i];
frag.appendChild(newChild);
}
cDiv.appendChild(frag); // hurray only once do you touch the live DOM
Useful JavaScript Fact – Did you know that you do not need to convert your object keys to strings unless they are a keyword in JavaScript –
var obj = {
"name" : "Nadu",
"is_human": true
"class": "Less Awesome"
}
// instead write
var obj = {
name : "Nadu"
is_human: true
"class" : "More Awesome"
}
Next planned article on jQuery and its goodness.
Credits
Ben Cherry’s (a Twitter Engineer) blog – http://www.adequatelygood.com
Paul Irish’s talk here