To understand this, you first need to understand JavaScript's object model.
As you'll have noted, when working with arrays, for...in loops aren't that useful because for (;;) loops do the job more easily.
But arrays are just a type of JavaScript object with numeric properties, and for (;;) loops only handle numeric properties. The reason for the notation myArray[0] is that you can use this square bracket notation for any property name. So myObject['myProperty'] is the same as myObject.myProperty. This is where for...in becomes useful:
for (var i in myObject) {
alert(myObject[i]);
}
So if the only property we'd set was myProperty, then i would equal "myProperty" (note that it's a string, which makes it more dynamic than just being a variable name).
There's a huge BUT here though. Objects have something called a prototype, and these prototypes have their own properties and methods. If I do the following:
for (var i in myArray) {
alert(i + ': ' + myArray[i]);
}
...I won't just get alerted with numeric values (1, 2, 3, etc.) I'll also get alerted with the array's properties such as length, and its methods such as join. These properties actually belong to the Array object's prototype, and the prototype properties can be filtered out by doing the following:
for (var i in myArray) {
if (myArray.hasOwnProperty(i)) {
alert(i + ': ' + myArray[i]);
}
}
Now I'll just get alerted with numeric values again, which means this is (almost) exactly the same as for (var i = 0;; i < myArray.length; i++). Why am I telling you this when we can just use that notation? Because all objects have prototypes, not just arrays. And every object descends from the Object object, so if somebody defined Object.prototype.myProperty = "some string value" then that would always show up in any for...in loop you use in the rest of the page. Thankfully, the hasOwnProperty method itself belongs to Object.prototype, so you can (and should) always use it in your for...in loops.
So here's a fully fledged for...in example:
// This is just one way of defining an object. We could also use a constructor function, or `new Object()`
var myObject = {
aProperty : "my first property value",
anotherProperty : "second property value"
4 : "numeric property names work too, you know"
}
for (var i in myObject) {
if (myObject.hasOwnProperty(i)) {
document.write(i + ': ' + myObject[i] + '<br />\n');
}
}
Output:
aProperty: my first property value
anotherProperty: secondPropertyValue
4: numeric property names work too, you know
Hopefully this explains it all.