Looping through object properties and hash tables using the “in” statement

As I said earlier, objects are hash tables of properties and functions so looping throught them is done the same way (weepee!).

The “in” statement

The in statement must be used in a for loop. Like this : for (var element in allElements). In most of the other languages, the element variable would contain the complete element but in javascript, it contains the name that refers to the complete element.

Looping through a hash table

Before doing it, maybe you should take a look at How to use javascript hashes (or hash-table) to make sure you fully understand what are javascript hash tables.

[source:javascript]

// I create a hash table
var hashPetNames = new Object();

// I create the pets
hashPetNames["cat"] = “Mistigri”;
hashPetNames["dog"] = “Rex”;
hashPetNames["bird"] = “Bibi”;

// I loop using the “in” statement
for (var name in hashPetNames) {
alert(”My ” + name + “’s name is ” + hashPetNames[name]);
}

[/source]

Run this code and you should see the alerts :
- My cat’s name is Mistigri.
- My dog’s name is Rex.
- My bird’s name is Bibi.

So easy.

Looping through an object

This one is a little kinkier. Why would I want to loop through an object properties and methods? I can’t give you an answer. It’s up to you to find it. I’ve used it a couple of times so it’s not as useless as you could think.

Example, I would like to separatly alert all the properties and methods of an object.

[source:javascript]

// Create the class
function TheClass() {
this.name = “The class”;
this.fullName = “The full name of the class”;
this.age = “51″;
}

// Add a function
TheClass.prototype.alertClass = function() {
alert(this.name + ” ” + this.fullName + this.Age);
}

// Construct the object
var theObject = new TheClass();

// Loop through the properties/functions
var properties = “”;
for (var propertyName in theObject) {
// Check if it’s NOT a function
if (!(theObject[propertyName] instanceof Function)) {
properties += propertyName + “, “;
}
}

alert(”Properties : ” + properties);

// Loop through the properties/functions
var functions = “”;
for (var functionName in theObject) {
// Check if it’s a function
if (theObject[functionName] instanceof Function) {
functions += functionName + “, “;
}
}

alert(”Functions : ” + functions);

[/source]

Comments

  1. BK April 2, 2007 at 10:09:53

    Are you sure this should not be listed under white belt? I think this is still simple language semantics. Or maybe blue belt! :P

  2. Aaron Faanes April 2, 2007 at 10:29:55

    Looping through objects like that is easier, but that means you’ll end up with the string of keys with a comma at the end (since you do += name + “, “;).

    var properties = [];
    for(var name in obj) {
    properties.push(name);
    }
    alert(properties.join(”, “);

    Will probably get you what you want. If you have Firebug, you could also use console.log to get a message in the log, instead of a popup dialog. (I really can’t emphasize enough the amazingness of _not_ having to alert() your log messages)

    Of course, you could also combine the two for-loops into:

    var properties = [];
    var functions = [];

    for(var name in obj) {
    if(obj[name] instanceof Function)
    functions.push(name);
    else
    properties.push(name);
    }

    You also probably’d want to join() the stuff in alertClass, otherwise you’ll end up with “The class The full name of the class51″. (By alert([this.name, this.fullName, this.age].join(” “)); )

    One important thing that I mentioned in another post is this very common bug with for(var i in obj).

    Let’s say you want to sum some numbers. So you want to take element, and then add it with the next, and so forth.

    var numbers = [1,2,3,4];
    var sums = [];
    for(var i in numbers) {
    if((i + 1) in numbers) // So that we don’t add a non-existent fifth element.
    sums.push(numbers[i] + numbers[i + 1]);
    }

    You’d probably assume (once you work through the “cleverness”) that you’d have [3, 5, 7] in sums, but sums will actually by empty. The reason for this is in the numbers[i + 1]. Javascript tries to be smart and do type coercion for you (0 == “0″) which is convenient alot of the time. However, here, i is “0″, “1″, etc., and _not_ 0, 1, 2. Javascript assumes you want strings over numbers, so it coerces the 1 to a string, instead of the i to a number, giving you “01″, “11″, “21″ as key values, which fails every time in our non-existent-fifth-element test.

    It’s a contrived example here, but it will happen to everyone out there, and it’s very insidious since it looks so innocent and correct.

    - Aaron

  3. Dan (maintainer of Javascript Kata) April 3, 2007 at 09:39:47

    @BK : I thought about creating and intermediate belt but it’s just too hard for the user to understand. White and black belts are known by everyone.

    @Aaron : Thanks for the correction. I was too lazy to write code without an additional “,” at the end.

    Thanks also to be such a great commenter. Even if your comments are most of the time caught by Akismet as spam ;)

  4. Dave March 5, 2008 at 12:07:22

    One year later… Was just googling for some syntax clarification and I saw this post.

    “in” can also be used in an expression, i.e.

    if (’index’ in { index: 0 }) // do stuff
    else // do other stuff

Post a comment

Comments are moderated and innapropriate ones won't be approved. Please respect this public space.