The scope of 'this'
Consider the following example:
function myClass(message) {
this.message = message;
$('button').click(function(){
this.onClick();
});
}
myClass.prototype.onClick = function() {
alert(this.message);
}
Of course, line 3 does not work: this
works on a per-function basis, and the function defined on line 2 will have the selected button as this
instead of the instance of myClass. There's an even sneakier version:
function myClass(message) {
this.message = message;
$('button').click(this.onClick);
}
myClass.prototype.onClick = function() {
alert(this.message);
}
This calls the correct function, but this
would still be the button (because this
is determined by the caller, not by the fact that you're a member function). The correct solution is to use an intermediate variable, such as self
, to apply sane scoping rules to this
:
function myClass(message) {
this.message = message;
var self = this;
$('button').click(function() { self.onClick(); });
}
Type casting
[] == ![]
evaluates to true for obscure reasons
Arrays and Properties
The length
property only works for integer keys on arrays. For instance:
var a = []; // a.length == 0
a[0] = 'first'; // a.length == 1
a['1'] = 'second'; // a.length == 2
a['x'] = 'third'; // a.length == 2 <-- 'x' does not count
While on this topic, for( in )
works on arrays, but traverses all properties defined on the array. This means that your JavaScript code that uses for( in )
to iterate through arrays will suddenly stop working on certain browsers when you add ExtJS to your project, because ExtJS defines Array.prototype.filter
if it's not present (this is known as monkey patching). Since now filter
is a custom property of every array object, all your loops also iterate through it. Boom.
The clean way of iterating through an array is using length and an incrementing for loop. Or jQuery's $.each()
.