I'm new to JavaScript and am learning about for...in loops and objects right now. I'm practicing with the following example:
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!') }
}
}
};
for (let crewMember in spaceship.crew){
console.log(`${crewMember}: ${crewMember.name}`);
}
The output of this code is that the console successfully logs crewMember, but not crewMember.name. crewMember.name is undefined, as in the image. On the other hand, when I change the log statement to this:
for (let crewMember in spaceship.crew){
console.log(`${crewMember}: ${spaceship.crew[crewMember].name}`);
}
the name of the crew member is logged successfully. I don't understand why I am able to access the crew member without going through the spaceship.crew in the first half of the console.log statement, but in the second half I have to go through spaceship.crew.
As said in the comment.
The for...in
loop fetches the property name as a key
. So it's a placeholder for captain
or 'chief officer'
. You can access a property via dot notation and bracket notation. Use brackets when using variables:
so:
spaceship.crew[crewMember]
That should work. See example:
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!') }
}
}
};
for (let crewMember in spaceship.crew){
console.log(`${crewMember}: ${spaceship.crew[crewMember].name}`);
}
And as Jared Smith said in his comment, use static methods instead:
So put of the objects own enumerable keys in an array using Object.keys
and iterate over them using forEach
and a Arrow function expression
.
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 | return all the keys
Object.keys(spaceship.crew).forEach( crewMember => {
console.log(`${crewMember}: ${spaceship.crew[crewMember].name}`);
});
//Object.entries | returns objects key and value in an array which you can iterate
Object.entries(spaceship.crew).forEach( ([crewMemberKey, crewDetails]) => {
console.log(`${crewMemberKey}: ${crewDetails.name}`);
});