2

I was going through one of codeacademy's javascript exercisees and ran into this. The following code is given by codeacademy.

var friends = {
    bill: {
        firstName: "Bill",
        lastName: "Gates",
        number: "1",
        address: ['abc', 'def', 'ghi']
    },
    steve: {
        firstName: "Steve",
        lastNAme: "Jobs",
        number: "2",
        address: ['abc', 'def', 'ghi']
    }
};

var list = function(obj) {
    for (var prop in obj) {
        console.log(prop);
    }
};

var search = function(name) {
    for (var prop in friends) {
        if (friends[prop].firstName === name) {
            console.log(friends[prop]);
            return friends[prop];
        }
    }
};

What I don't understand is, in the search function, why I need to write out 'friends[prop]' instead of just 'prop'. If the for/in loop is iterating through every property in friends(array?), why do I need to specify again what array each prop belongs to? Why can't I use the following code?

var search = function(name) {
    for (var prop in friends) {
        if (prop.firstName === name) {
            console.log(prop);
            return prop;
        }
    }
};
jeebface
  • 841
  • 1
  • 12
  • 29
  • 1
    Well, this is because for loops in JavaScript are a bit confusing. Check http://stackoverflow.com/a/9329476/60518 – Tim Büthe Jun 05 '13 at 09:03
  • please read the edit i made to my answer - it's quite important or you might run into unexpected errors. – Christoph Jun 05 '13 at 09:32

3 Answers3

6

prop actually is the name of the object's property (=key), not the property itself. It's a plain string ("bill") and not the actual object friends.bill (/a reference to it).

This is also the reason, why you write

friends[prop] // prop gets evaluated here, it's value is the identifier

instead of

friends.prop  // prop is treated as the identifier here

Example:

var friends = {
    bill: { ...
    }
}
for (var prop in friends) {
    // prop == "bill";
    friends[prop] == friends.bill 
}

Actually, this is similar to (the new) Object.keys(friends) which returns you an array of all property names of the object you could then iterate on (which perhaps is a bit more intuitive for people coming from other languages).

EDIT: One important note!

Unlike Object.keys(), for in lists all properties of your object, even those it inherited from it's prototype. So if you want to make sure you only get your "native" properties, you always have to check if it's a genuine property of the object:

for (var prop in friends) {
    if (friends.hasOwnProperty(prop) ){
         // it's a true property of your object
    }
}
Christoph
  • 50,121
  • 21
  • 99
  • 128
2

for..in iterates for the keys of the object, not the values.

In case you're familiar with PHP:

foreach ($friends as $prop => $value) ...

for..in only gives you $prop, not $value. To get $value, you need to use $friends[$prop], or in Javascript terms friends[prop].

deceze
  • 510,633
  • 85
  • 743
  • 889
1

Think of the variable prop as the key in a key->value pairing.

The statement friends[prop] is specifying the key named prop's value of the object friends.

If you instead say prop.firstname, you are actually specifying the property firstname of the string assigned to prop, which makes no sense, since prop is not an object.

Derek Henderson
  • 9,388
  • 4
  • 42
  • 71