Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialsaber
13,276 PointsHow does forEach pass the username to getProfile?
I got lost on this one when Andrew wrote:
users.forEach(getProfile);
I thought for sure we would have to write something like:
users.forEach(username => {
getProfile(username);
});
How does getProfile get the username passed to it as an argument? Is this some new fancy ES2015 magic that it's smart enough to know to pass what forEach returns on each iteration to the get getProfile function as its argument?. I'm guessing it's either that, or something to do with closures.
2 Answers
Steven Parker
231,261 PointsThe "foreEach" method always passes 3 arguments to the function it calls: the current item, the item's index number, and the container itself. The function doesn't need to use all of these, or even any, but it's very common to use just the first one as in the example you have given.
This mechanism itself isn't really new, and is very much like how an event handler function is passed the event object.
Also, if you re-examine your examples you'll see that they both rely on the argument passed by "forEach". In the first it is received directly by getProfile, and in the second it is received by an anonymous function which then passes it along to getProfile.
Michael Braga
Full Stack JavaScript Techdegree Graduate 24,174 PointsWe cant directly see (not that I know of) what is actually happening within the forEach method call. But the code would be something like this:
NOTE: This is just pseudo code to show that something similar is happening within the forEach call
function forEach(callback) {
let array = this;
for(let i = 0; i < array.length; i++) {
callback(array[i], i, array);
}
}
Once I understood this, iteration method calls (forEach, reduce, map) became very easy to understand. Hope this helps for anyone who is confused.
Trevor Maltbie
Full Stack JavaScript Techdegree Graduate 17,021 Pointsand "this " is referring to what again? :/
saber
13,276 Pointssaber
13,276 PointsThat's what I wasn't expecting to be possible. I didn't know it was possible for getProfile to directly receive an argument from the forEach just by passing getProfile's function name only without passing it an argument in parens. I'm trying to understand how that works.
Steven Parker
231,261 PointsSteven Parker
231,261 PointsThat's not unique to forEach, that's just typical callback behavior. Remember that you only pass the function itself as a callback argument, either by name or by providing an anonymous function expression. But the code that uses that function is in control of how it is called, and what arguments it passes to it.
saber
13,276 Pointssaber
13,276 PointsYeah I get that it's not unique to forEach. But just to make sure I understand. If I were to use forEach as an example... are you saying that I could define a callback function that takes 3 arguments... then pass it by name only as the callback argument for forEach... and forEach would give my callback the currentValue, index, and array? Like this?
If so, clearly I need to go back and review how callbacks work... because I've always just passed an anonymous function.
Steven Parker
231,261 PointsSteven Parker
231,261 PointsYes, that's exactly right. And it doesnt matter if you pass a named function or an anonymous function expression. Either one will still get the same things passed to it, and can be written to accept one or more of them as arguments.
Adding to your example, you could also create the same callback as a function expression:
someArray.forEach((currentValue, index, array) => { /* do stuff */ });
saber
13,276 Pointssaber
13,276 PointsAnd the function expression is how I've always done it. Either that way or with the old ES5 syntax. You've been a tremendous help. Thanks for taking the time to explain all that!