var myBulletinBoardAppGlobals = {
foo: "some value",
bar: null
};
Or consider using a namespace prefix (a.k.a., a special naming convention):
CPWFoo = "some value";
CPWBar = null;
These practices prevent your global variables from colliding with global DOM objects present in the runtime.
var o = { // better than var o= new Object; o.name= ... (etc.)
name: 'Jeffrey',
lastName = 'Way',
someFunction : function() {
console.log(this.name);
}
};
var o = {};
var a = ['Joe','Plumber']; // better than var a= new Array()
function total() {
var theform = document.forms["myform"];
var total = (+theform.elements["val1"].value) + (+theform.elements["val2"].value);
alert(total); // This will alert 3
}
Not As Good
<form name="myform" action="[url]">
<input type="text" name="val1" value="1">
<input type="text" name="val2" value="2">
</form>
function total() {
var theform = document.forms["myform"];
var total = theform.elements["val1"].value + theform.elements["val2"].value;
alert(total); // This will alert "12", but what you wanted was 3!
}
'' = = '0' // false
0 = = '' // true
0 = = '0' // true
false = = 'false' // false
false = = '0' // true
false = = undefined // false
false = = null // false
null = = undefined // true
' \t\r\n ' = = 0 // true
setInterval(
"document.getElementById('container').innerHTML += 'My new number: ' + i", 3000
);
Not only is this code inefficient, but it also functions in the same way as the "eval" function would. Never pass a string to SetInterval and SetTimeOut. Instead, pass a function name or the anonymous function.
setInterval(someFunction, 3000);
OR
setTimeout(function () {
// Code to execute on a timeout
}, 50);
var arr = ...;
var globalVar = 0;
(function () {
var i, l, localVar;
l = arr.length;
localVar = globalVar;
for (i = 0; i < l; i++) {
localVar++;
}
globalVar = localVar;
})();
Not As Good
var arr = ...;
var globalVar = 0;
(function () {
var i;
for (i = 0; i < arr.length; i++) {
globalVar++;
}
})();
if (/loaded|complete/.test(document.readyState)) {...}
var a = 1, b = 2, c;
c = a < b ? a : b; var a = 1, b = 2, c;
c = Math.min(a, b);
Not As Good
var a = 1, b = 2, c;
c = Math.min(a, b);
Good Practice
myArray[myArray.length] = value;
myArray[idx++] = value;
myArray.push(value);
Not As Good
myArray.push(value);
var i;
try {
for (i = 0; i < 100000; i++) {
...
}
} catch (e) {
...
}
Not As Good
var i;
for (i = 0; i < 100000; i++) {
try {
...
} catch (e) {
...
}
}
var i, value, length = myArray.length;
for (i = 0; i < length; i++) {
value = myArray[i];
...
}
Not As Good
var key, value;
for (key in myArray) {
value = myArray[key];
...
}
var fn;
if (...) {
fn = function () {...};
} else {
fn = function () {...};
}
Not As Good
function fn () {
if (...) {
...
} else {
...
}
}
document.getElementsByTagName('*').length
var i, j, el, table, tbody, row, cell, docFragment;
docFragment = document.createDocumentFragment();
el = document.createElement("div");
docFragment.appendChild(el);
table = document.createElement("table");
el.appendChild(table);
tbody = document.createElement("tbody");
table.appendChild(tbody);
for (i = 0; i < 1000; i++) {
...
}
document.body.appendChild(docFragment);
var i, j, el, idx, html;
idx = 0;
html = [];
html[idx++] = "<table>";
for (i = 0; i < 1000; i++) {
html[idx++] = "<tr>";
for (j = 0; j < 5; j++) {
html[idx++] = "<td></td>";
}
html[idx++] = "</tr>";
}
html[idx++] = "</table>";
el = document.createElement("div");
document.body.appendChild(el);
el.innerHTML = html.join("");
Not As Good
var i, j, el, table, tbody, row, cell;
el = document.createElement("div");
document.body.appendChild(el);
table = document.createElement("table");
el.appendChild(table);
tbody = document.createElement("tbody");
table.appendChild(tbody);
for (i = 0; i < 1000; i++) {
row = document.createElement("tr");
for (j = 0; j < 5; j++) {
cell = document.createElement("td");
row.appendChild(cell);
}
tbody.appendChild(row);
}
var i, el, table, tbody, template, row, cell;
el = document.createElement("div");
document.body.appendChild(el);
table = document.createElement("table");
el.appendChild(table);
tbody = document.createElement("tbody");
table.appendChild(tbody);
template = document.createElement("tr");
for (i = 0; i < 5; i++) {
cell = document.createElement("td");
template.appendChild(cell);
}
for (i = 0; i < 1000; i++) {
row = template.cloneNode(true);
tbody.appendChild(row);
}
Not As Good
var i, j, el, table, tbody, row, cell;
el = document.createElement("div");
document.body.appendChild(el);
table = document.createElement("table");
el.appendChild(table);
tbody = document.createElement("tbody");
table.appendChild(tbody);
for (i = 0; i < 1000; i++) {
row = document.createElement("tr");
for (j = 0; j < 5; j++) {
cell = document.createElement("td");
row.appendChild(cell);
}
tbody.appendChild(row);
}
var names = ['George','Ringo','Paul','John'];
var all = names.length;
for(var i=0;i<all;i++){
doSomeThingWith(names[i]);
}
...OR...
var names = ['George','Ringo','Paul','John'];
for(var i=0,j=names.length;i<j;i++){
doSomeThingWith(names[i]);
}
Not As Good
var names = ['George','Ringo','Paul','John'];
for(var i=0;i<names.length;i++){
doSomeThingWith(names[i]);
}
[Editor's Note] These tips appear to have been compiled from numerous web sites. Here is a partial listing:
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (2)
Commented:
As a long-time JavaScript programmer, I'd like to say that I take issue with many of the tips above. For most of them, there is no background or explanation as to why they should be used, and in fact, the "performance optimization" that can (or I really should say might under some circumstances) be obtained is often so trivial as to be not worth mentioning.
It is too bad that you did not provide documentation, benchmark timing tests, or other information that would be so helpful. That would have made this a much better article.
Commented:
why should i as example avoid recursion?
recursion can be even more performant in some cases if it is done right then you think.
have you ever tryed using call() or apply()?
sharing the same scope with theese methods would result in a single scope for a whole recursion.
also some of your code like 22 is not correct. why should i write with a loop into a -variable-?
your function there overrides the same variable on each loop run.
also your code example at 20 does not make sense. just look at it and you see what i mean.
your point 18 does not make sense because for the javascript core its no efford to convert that to a real expression.
if you mentioned this then why didnt you told us to remove all unneeded spacing and new lines? and specialy comments?
sorry but i just cant feel the love to javascript in your article.
you talk about scopes but do not even talk about prototypes.