FAQ: Objects - Looping Through Objects

crewMember is defined here:

for (let crewMember in spaceship.crew ){

JS will now do a lot of heavy lifting for you, assigning each key of the crew object to your crewMember iterable.

I wonder if you could explain again why the square brackets are needed for crewMember in:

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

as opposed to spaceship.crew.crewMember.name.

You had previously said “…the loop gives you a string, when accessing an object property as string, you have to use associative array notation.”

But I don’t understand what that means at all, sorry and thank!

(are we saying crew[crewMember] in the same way we would say array[index]? if so, is the spaceship object an array? :S)

Close, objects are associative arrays (and vice versa). Which means we have two ways, using a property:

obj.prop

or to use a key:

obj['key']

using the property/object notation only works with the property name, not with a string.

link: https://www.codecademy.com/paths/web-development/tracks/web-dev-js-arrays-loops-objects/modules/learn-javascript-objects/lessons/objects/exercises/for-in

on item 1, the result to log is

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

Just to confirm, let crewMember creates a variable that reaches each of the objets values inside the parameter crew, is that right? so each object inside crew will be inside the “crewMember” variable. is that right?

If I write let crewMember in spaceship.crew.name, then the variable would only contain all the values of the names of the crew. is it right?

I came to this conclusion considering that ``${crewMember}:` brings the objects inside of Crew, I just want to confirm.

no, crewMember will contain the properties/keys of the crew object as string ('captain', 'medic' and so forth).

no, given crew object doesn’t have .name property/key. Doing:

spaceship.crew.name

will give undefined. So the loop won’t even run.

Nice, just tried that. So there is no way to access crew member 's name without creating a new variable, just like we did with memberCrew?

we can do spaceship.crew.captain.name, and so forth. We create no new variable. But its a lot more work. A loop is then easier/better.

1 Like

Thank you. It would’t be more wise, when creating those nested objets, instead of captain, engineer etc, to put "profession: captain"; ? that would eliminate the necessity of creating a variable to reach the values, wouldnt it?

And what about using .this ?

but the crewMembers (captains and the rest) have multiple properties. This nested structure is better, and we don’t want duplicate data.

1 Like

Why can’t you use this?

I guess I’m wondering what the in actually means. I know it’s wrong but my understanding is that crewMemberRole represents all objects under spaceship.crew. So why can’t I use crewMemberRole.name instead of spaceship.crew[crewMemberRole].name?

Thanks!

It’s a type of for-loop.

for(let crewMemberRole in spaceship.crew) iterates through every item in crew. So when you call ${crewMemberRole}, crewMemberRole is going to be returned as captain, medic, etc. for every value of spaceship.crew.

You’re already calling spaceship.crew values so you don’t need to re-state it.
You can’t say spaceship.crew[crewMemberRole].name as that would already be like saying spaceship.crew.name.name (since crewMemberRole is already the crew.name.

Hi there, are you a learner too if you don’t mind me asking? Sorry for the confusion but what I mean was:
spaceship.crew[crewMemberRole].name is actually correct and crewMemberRole.name is wrong?

1 Like

I was wrong (wrote it too hastily). I didn’t realize that name referred to the person’s name rather than the role’s name. The iteration part should still check out. Thanks for clarifying that.

I have some years with java and comfortable with python. JS is not my forte but I’m pretty comfortable with iteration…

1 Like

Doesn’t work for some reason but thanks anways !

I’m still getting my head around it tbh but we use ${}, string interpolation to hold and log or return our string.

We assign the variable crewMember to spaceship.crew and when we want to access the value of this we use , otherwise we simply access the key name (captain, medic, etc) with the string interpolation, ${}

String interpolation refers to constructing or printing strings, only. It is not part of any logic. ${} is the placeholder for the value or expression we wish to insert in the string.

Compare this to concatenation.

a = 3
b = 4
s = 'The length of the hypotenuse of a right\
 triangle with side, ' + a + ', and base, ' + b + ', is,\
 ' + Math.sqrt(a ** 2 + b ** 2) + '.'
console.log(s)
The length of the hypotenuse of a right triangle with side, 3, and base, 4, is, 5.

Thanks to JS’s ability to coerce numbers to string we didn’t have to cast the value to string. In the background, it is doing,

a.toString()

Could we use the for…in loop to iterate through methods??

This may look silly, but examine it closely for clues.

obj = {
  one: function() { return this.one.toString() },
  two: function() { return this.two.toString() }
}
for (let x in obj) {
  console.log(obj[x]())
}

Output

function () { return this.one.toString() }
function () { return this.two.toString() }

On an object literal we can get an inventory of the property names…

props = Object.getOwnPropertyNames(spaceship)
console.log(props)

As far as iterating over the methods, that is still to be determined with more reading and testing.

Hello,
I’m a bit baffled why I keep getting a console.log error message when I post the following to question 1 of Lesson 9:

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

Hope I’m not missing a typo but I’ve been stuck on this for far too long yet when I cut and paste the “solution” as written at the end of Lesson 9 example explanation I get a pass :white_check_mark: onto the next question.

If wiser minds see this as a bug, I’ll be happy to report it as such.

Thanks…