Javascript Arrays and Loops (level: beginner/intermediate)

Objectives

Understand the difference between different types of Array and Loop concepts and when to use each type

  • Overview of javascript Arrays
  • Overview javascript Loop constructs

Beginners: Don't worry if you don't understand all this, it's really not that important! loops are pretty much interchangeable (with a couple of exceptions). In some cases you won't be able to use a for loop though so it's worth having a quick look at the other options.

Arrays

Firstly, we'll have a quick look at arrays. Bassically, there is one type of array in javascript (more about hashtables in a bit), to create an array you simply create an empty Array(). Javascript arrays will grow so you don't need to define the size when you create them.

var myArray = new Array();
// or
var myArray = [];

You can popuplate an array when you create it, or later

var myArray = new Array("x","y","z");
// or 
var myArray = new Array();
myArray[myArray.length] = "x";
myArray[myArray.length] = "y";
myArray[myArray.length] = "z";
// or 
var myArray = new Array();
myArray.push("x");
myArray.push("y");
myArray.push("z");

Arrays can contain ints, strings, objects and other arrays, also you can mix them up

var myArray1 = new Array(1,2.00,"three")
var myArray2 = new Array("x",2,new Object(),myArray1);

Have a look at all the array properties and methods

Arrays (hashtable)

A hashtable in javascript is really an object and NOT an array at all, you can't find the length of it or use any of the Array methods like .push(). The hashtable can be very useful and, as ever, there are a number of ways you can create one.

var myHashtable = {
	name : "Douglas",
	phone : "07980 00000",
	email : "email@anaddress.com"
}
//or 
var myHashtable = {};
// or 
var myHashtable = new Object;

myHashtable["name"] = "Douglas";
myHashtable["phone"] = "07980 00000";
myHashtable["email"] = "email@anaddress.com";

To retrieve a value from a hashtable you need to reference it by name, you can't use a index like in a normal array as it doesn't have one.

alert(myHashtable[0]) // will error ;
alert(myHashtable['name']) // will alert "Douglas" ;
// or 
alert(myHashtable.name) // will also alert "Douglas" ;

Loops

There are two basic loop constructs in javascript for and while. The for loop is for looping though arrays where your script knows how long the array is and the while loop is for when you don't. Since in javascript you always know how long an Array is the for loop is commonly used (we'll look at when you might want to use a while loop shortly).
The syntax is:
for ( [initiate_variable_counter] ; [loop_condition] ; [increment_counter] ) {
[code_block]
}

the [code_block] will be executed while the [loop_condition] evaluates to true. As soon as the [loop_condition] is false it will exit the loop. It's worth noting that the execution order is [initiate_variable_counter], [loop_condition], [code_block], [increment_counter] then back to [loop_condition] and the last three keep executing until [loop_condition] is false. It's quite easy to crash the browser if you put some test which will never be false!

Typically a for loop looks like this

var myArray = new Array(1,2,3)
for (var i = 0; i < myArray.length ; i++ ){
	document.writeln( myArray[i] + "<br/>" );
}

If your going to delete things from your array your better off going backwards, if your only deleting some things you'll have to go backwards or you'll have problems

// going backwards
var myArray = new Array(1,2,3,4,5,6,7,8,9)
for (var i = myArray.length; i > 0 ; i-- ){
	// remove 4, 5 and 6
	if ( myArray[i-1] == 4 || myArray[i-1] == 5 || myArray[i-1] == 6  ) {
		myArray.splice(i-1,1);
	}	
}
document.writeln(myArray) // will write 1,2,3,7,8,9 as expected

// going forwards
var myArray = new Array(1,2,3,4,5,6,7,8,9)
for (var i = 0; i < myArray.length ; i++ ){
	// remove 4, 5 and 6 ? 
	if ( myArray[i] == 4 || myArray[i] == 5 || myArray[i] == 6 ) {
		myArray.splice(i,1);
	}	
}
document.writeln(myArray) // will write 1,2,3,5,7,8,9 NOT as expected
// 10 points to you if you can workout why! 
// just make sure you go backwards if your removing things

There is an enumeration capability built into for loops, this is pretty much the same as the normal farward for loop in the previous example, except you can use this both on normal arrays AND hashtables.

var myArray = new Array(1,2,3,4,5,6,7,8,9)
for ( var i in myArray ){
	document.write( myArray[i] +", " );
}
// will write
1, 2, 3, 4, 5, 6, 7, 8, 9, 

var myHashtable = {
	name : "Douglas",
	phone : "07980 00000",
	email : "email@anaddress.com"
}
for (var name in myHashtable){
	document.writeln( name + " = " + myHashtable[name] + ", " );
}
// will write
name = Douglas, phone = 07980 00000, email = email@anaddress.com,

while loops are pretty much the same as for loops, just simpler, you only have the [loop_codition] test, so the [code_block] will be exectuted while the [loop_condition] can be evaluated to true.
The syntax is:
while ( [loop_condition] ) {
[code_block]
}

the do {...} while (..) statment is just the same, the only difference is that the [code_block] will get exectuted once no matter what (I'm trying to remember a time where I've used a do while loop in javascript and quite honestly, I can't!).

while ( false ) {
	alert('hello'); // this will not happen
}
do {
	alert('hello'); // this will happen once
} while ( false )

The while loop can be very useful if you don't want to bother finding out the array length or your not looping though an array

// we don't know the array length
while ( node.nextSibling ) {
	node.doSomething()
	node = node.nextSibling;
}
// we are walking up the dom tree looking for a <div /> container element
while ( node.parentNode ){
	if ( node.tagName == "DIV" ){
		alert("this is the containing div " + node.id);
		break;
	}
	node = node.parentNode;
}

In the previous example we can see a break statment you can jump out of a loop (while or for) at any time by using the break key word. In both examples the code block will keep exicuting until the node has no nextSibling or parentNode.

Variables / Scope

Loops can catch you out sometimes, let's say we want to attach an onclick event to the following buttons to alert their current value:

<input type="button" id="button01" value="button 1" />
<input type="button" id="button02" value="button 2" />
<input type="button" id="button03" value="button 3" />
<input type="button" id="button04" value="button 4" />
<input type="button" id="button05" value="button 5" />
<input type="button" id="button06" value="button 6" />

Try to attach a onclick event using the this keyword. IE will think that this means the window object

<script>
function AttachButtonEvents(){
  var el;
  for (var i=1;i<7;i++) {
	el = document.getElementById('button0'+i);
	if (el.addEventListener) {
		el.addEventListener('click',function(){
			 alert( this.value ) // will alert the button value e.g. "button 1"
		},false);
	} else if (el.attachEvent) { // IE
		el.attachEvent('onclick',function(){
			 alert( this.value ) // will alert the window value probably "undefined"
		});
	}
  }
}
AttachButtonEvents()
</script>

try to add the onclick event by using the el var

<script>
function AttachButtonEvents(){
  var el;
  for (var i=1;i<7;i++) {
	el = document.getElementById('button0'+i);
	if (el.addEventListener) {
		el.addEventListener('click',function(){
			 alert( el.value ) 
			 /* clicking on any button will alert 
			 the last button value e.g. "button 6" */
		},false);
	} else if (el.attachEvent) { // IE
		el.attachEvent('onclick',function(){
			 alert( el.value ) 
			 /* clicking on any button will alert 
			 the last button value e.g. "button 6" */
		});
	}
  }
}
AttachButtonEvents()  
</script>

Neither of the above will do what we want. We need to attach the onclick event handeler out side of the scope of the loop

<script>
function AttachButtonEvents(){
  var el;
  for (var i=1;i<7;i++) {
	el = document.getElementById('button0'+i);
	AddEvent(el);
  }
  
  function AddEvent(el){
	if (el.addEventListener) {
		el.addEventListener('click',function(){
			 alert( el.value ) 
			 /* clicking on any button will alert 
			 the it's own value */
		},false);
	} else if (el.attachEvent) { // IE
		el.attachEvent('onclick',function(){
			 alert( el.value ) 
			 /* clicking on any button will alert 
			 the it's own value */
		});
	}
  }
AttachButtonEvents();  
</script>

Conclusion

We've had a look at arrays and hashtables, how to create them, loop though them and how to loop backwards though an array.
We've looked at the difference between for loops and how and when to use a while loop. Best of luck with your javascripting!

- ends -