Common JavaScript Mistakes
Syntax: Having an additional trailing comma
In Prototype-style classes, we often write our code in this fashion:
var Rectangle = Class.create({
initialize: function() {
// Do something
},
fooize: function(a,b) {
return a * b
// ERROR
},
})
Semantic: Forgetting to declare a variable
Many JavaScript programmmers forget to explicitely declare variables
by using the var keyword. The variable gets declared in the
global scope, and the variable can be modified anytime by another function
which uses the same unprefixed variable.
var Utility = {
getSize: function(x1, y1, x2, y2) {
size = [x2-x1, y2-y1];
return size;
}
};
var Rectangle = Class.create({
initialize: function(x,y,w,h) {
size = [w, h];
boundingBox = Utility.getSize(x-5, y-5, x + w+5, y + h+5);
// ERROR
this.size = size;
}
});
var r = new Rectangle(10,10,100,100);
alert("Rectangle.size is " + r.size.toSource());
Semantic: Not preserving this when giving a method as callback
Callbacks are heavily used in JavaScript, and when doing OO programmming in JavaScript, we often have to give methods as callbacks for event handling or AJAX. The problem is that the original context of the method (the instance) is not preserved, so that the callback will be executed in the caller context.
var Widget = Class.create({
initialize:function(){
this.clicks = 0;
},
onClick: function() {
this.clicks += 1;
}
});
var widget = new Widget();
// ERROR
$(".counter.button").bind("click", widget.onClick);
$(".counter.button").bind("click", function(){alert("Clicks: " + widget.clicks)});
Semantic: Looping over an array slots instead of its elements
The for( var x in ...) JavaScript statement can be quite confusing, because
it does not behave as Python or Ruby programmmers would expect. The for( var x in ...)
actually iterates over an object slots. Arrays being objects, not only will you get indices of array elements
instead of the elements themselves, but you will have the name of any additional slot defined in the array.
var a = ['a', 'b', 'c'];
// We add a custom slot
a.elementsCount = 3;
var r = "";
for ( k in a ) {
r += "value:" + k + " ";
};
alert("Result: " + r);
Semantic: Closures definition in for loops
Scoping rules in JavaScript are sometimes a bit strange. Most of the time creating a closure will take a snapshot of its environment, but in some cases, it just don't.
function f(selector) {
var inputs = $(selector);
for ( var i=0 ; i<inputs.length ; i++ ) {
// ERROR
var input = inputs[i];
$(input).bind("click", function(){
alert("Input " + $(input).attr("name") + " was clicked");
})
}
};
f("input.button");