skip to Main Content

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.

3

Answers


  1. 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(spaceship.crew).forEach( crewMember => {
      console.log(`${crewMember}: ${spaceship.crew[crewMember].name}`);
    });
    Login or Signup to reply.
  2. Someone mentioned Object.entries( which can also be used to add clarity from a properly formed object by coercing them into an array-like object so here is an example of that for the spaceship.crew object we can use good names for crewMembers an then crewMember or just member some such which can add clarity of purpose and intent also when we do this. Note this is less "brackety" since we have named properties of the objects. Note how crewMember is an object then.

    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}`);
    }
    //console.log(Object.entries(spaceship.crew));
    
    //console.log([...Object.entries(spaceship.crew)]);
    
    
    [...Object.entries(spaceship.crew)].forEach((crewMmembers) => crewMmembers.forEach(function(crewMember, index, mArray) {
      console.log(crewMember, index);
      console.log(`At ${index} We have ${crewMember.name}: ${crewMember.degree}`);
      console.log(`And ${crewMember}`);
    }));
    Login or Signup to reply.
  3. Someone mentioned Object.entries( which can also be used to add clarity from a properly formed object by coercing them into an array-like object so here is an example of that for the spaceship.crew object we can use good names for crewMembers an then crewMember or just member some such which can add clarity of purpose and intent also when we do this. Note this is less "brackety" since we have named properties of the objects.

    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}`);
    }
    //console.log(Object.entries(spaceship.crew));
    
    //console.log([...Object.entries(spaceship.crew)]);
    
    
    [...Object.entries(spaceship.crew)].forEach((crewMmembers) => crewMmembers.forEach(function(crewMember, index, mArray) {
      console.log(crewMember, index);
      console.log(`At ${index} We have ${crewMember.name}: ${crewMember.degree}`);
      console.log(`And ${crewMember}`);
    }));
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search