FAQ: Objects - Looping Through Objects

member is a variable containing a string, so in your example its similar to 'back-up'.

we can only uses keys to look up values in an object, keys itself do not contain information associated information about an object

But back-up is a key that we use to look up it’s value battery. So if member is similar, then member.name should work just as ['back-up'].battery works above.

it does:

for (const member in spaceship.crew) {
  console.log(spaceship.crew[member].name)
}

the loop simply means we get all the crew names instead of just a single one with a hard-coded key (like back-up)

I’m sorry I know im going in circles but Im really trying to grasp this lol.

Each member in the loop references an object with a name property as I understand

for (const member in spaceship.crew) {
  console.log(member.name)
}

So doing this should work if we just wanted each crew member’s name. Is this logic wrong?

member is not an object. If you attempt to log member and its type:

console.log(member, typeof member);

you will see member is a string, which we can use as key to look up information of spaceship crew

My god I’m stupid, apologies I get it now

Calling a function Looping Through Objects using the For … In

Hey guys, I don’t know if you already passed by this point, by I saw the functions inside of the object spaceship but each one with a different name, so came the question, how to call each function if they don’t follow a pattern like spaceship.crew.translator.name, so if I want to call each one like Shauna has the function powerFuel() I need to call spaceship.crew.translator.powerFuel(). However, as each one has a different function you can loop again Nested loops, ask the type of the object using typeof and call it using spaceship.crew[crewMember][details]()

I hope it will be usefull :wink:

for (let crewMember in spaceship.crew){
  console.log(`${crewMember} - ${spaceship.crew[crewMember].name}: ${spaceship.crew[crewMember].degree}`)

  console.log('---> Getting the type of the attribuites using typeof')
  for (details in spaceship.crew[crewMember]){
    console.log(`${details}: ${typeof(spaceship.crew[crewMember][details])}`)
    if (typeof(spaceship.crew[crewMember][details]) == 'function'){
      spaceship.crew[crewMember][details]()
    }
  }
  console.log('\n')
}

I am having quite some challenges going through this class. Could someone help me understand better? Thanks!

I am a bit lost on why there is a difference in using the dot notation and bracket notation to access the degree property for each crew member.
Below is the code and error thrown.

for (let member in spaceship.crew) {
  console.log(spaceship.crew[member][degree]) // `ReferenceError: degree is not defined at Object.<anonymous> `
  console.log(spaceship.crew[member].degree) // this works
1 Like

Documentation:

Bracket Notation
In the object[expression] syntax, the expression should evaluate to a string or Symbol that represents the property’s name. So, it can be any string literal, for example, including ‘1foo’, ‘!bar!’, or even ’ ’ (a space).

// As you said this works:
console.log(spaceship.crew[member].degree) 

// For bracket notation, you could do:
console.log(spaceship.crew[member]["degree"]); // This will work
console.log(spaceship["crew"][member]["degree"]);  // This will work

// This won't work because crew is not in quotes
console.log(spaceship[crew][member]["degree"]); 

// If you are wondering why quotes aren't needed for member,
// (let member in spaceship.crew) takes care of ensuring member is a string.
1 Like

got cha! Thank you so much for the comprehensive response. Makes total sense!

1 Like

In this exercise, the spaceship object contains multiple obejcts, which then contain more objects - a lot of nesting is going on.
Are the nested objects (inner objects) still properties of the outer objects? E.g.

let spaceship = {
engine: 'warp',
color: 'blue',  
crew: {
    captain: { 
      name: 'Lily', 
      degree: 'Computer Engineering', 
      cheerTeam() { console.log('You got this!') } 
    }
  }
}; 

Is crew a property of spaceship in the same way as color and engine?
Also, is name a property of captain in the same way that captain is a property of crew (is there a difference between properties of outer objects and those of nested objects)?

2 Likes

Short answer, no. Only ‘engine’, ‘color’ and ‘crew’ are properties of spaceship. The nested object is the value of the crew property.

for (let crewMember in spaceship.crew) {
console.log(${crewMember}: ${spaceship.crew[crewMember].name})
}

Are there any other circumstances that we cannot use the “dot notation” over the array notation? I mean when must we use only the array notations? and when must we only use the “dot notation”? And when can we use both?

Quick question, to further understand this.

Can you only access properties within the first set of curly braces within an object?

Using the below example as I am just looking for clarification. You wouldn’t be able to access name or degree by using the dot notation because they are values of their key, which is either captain, ‘chief officer’, medic or translator, and those keys are all properties of the inner object of crew?

let spaceship = {
    crew: {
    captain: { 
        name: 'Lily', 
        degree: 'Computer Engineering', 
        cheerTeam() { console.log('You got this!') } 
        },
    'chief officer': { 
        name: 'Dan', 
        degree: 'Aerospace Engineering', 
        agree() { console.log('I agree, captain!') } 
        },
    medic: { 
        name: 'Clementine', 
        degree: 'Physics', 
        announce() { console.log(`Jets on!`) } },
    translator: {
        name: 'Shauna', 
        degree: 'Conservation Science', 
        powerFuel() { console.log('The tank is full!') } 
        }
    }
}; 
 > Object.keys(spaceship)
   ['crew']
 > Object.keys(spaceship.crew)
   ['captain', 'chief officer', 'medic', 'translator']
 > Object.keys(spaceship.crew.captain)
   ['name', 'degree', 'cheerTeam']
 > Object.values(spaceship.crew.captain)
   ['Lily', 'Computer Engineering', ƒ]
 > spaceship.crew.captain.name
   'Lily'
 > spaceship.crew.captain.cheerTeam()
   You got this!
1 Like

what is the meaning/working of “in” in the syntax of “for…in” loop

The in operator refers to members of an object by key, as in,

for (let key in object) {

}

Once we have a key from within the object, we can access its associated value:

console.log(object[key])

Note the bracket notation syntax.

const object = {
    R: 'red',
    O: 'orange',
    Y: 'yellow',
    G: 'green',
    B: 'blue',
    I: 'indigo',
    V: 'violet'
}

The capital letters are the keys, and the quoted strings are the values. We should note that in JavaScript, keys are string objects, always, even when entered without quotes. If there is whitespace in the key name, it must be written in quotes.

 > Object.keys(object)
   ['R', 'O', 'Y', 'G', 'B', 'I', 'V']
 > Object.values(object)
   ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']

We can use the in operator to test for membership of a key, but not for a value.

 > 'V' in object
   true
 > 'violet' in object
   false
const get = function (obj, key) {
    if (key in obj) {
        return obj[key]
    }
    return false
}
 > console.log(get(object, 'B'))
   blue
 > console.log(get(object, 'K'))
   false

Lastly, pertaining to iteration,

for (let key in object) {
    console.log(`${key}: ${object[key]}`)
}
R: red
O: orange
Y: yellow
G: green
B: blue
I: indigo
V: violet

Special note: This operator is intended for use with objects, not arrays. It seeks out keys, not values. When seeking values in an array, we use the of operator. That is for another discussion.

2 Likes

Thank you so much for explaining the working of “in” with easy to understand examples. I have a question from above example why you didn’t put “quotes” in using bracket notation like below:

1) console.log(object['key']) 
2) return obj['key']
1 Like

Quotes define string literals. We do not have a key with the literal name, ‘key’. In our example, key is an identifier variable.

console.log(object['V'])    //  violet

Bottom line, only ever use quotes when addressing an exact key name.

1 Like