I'm currently undertaking JavaScript: The Hard Parts v2 course at Frontend Masters. It is a brilliant course taught by the amazing Will Sentance. T...
For further actions, you may consider blocking this person and/or reporting abuse
Being that this is intended to teach "the hard parts of JavaScript" I think you should take some care to not teach bad habits inadvertently as well.
Specifically exercise 6. You're reusing
initialValue
as your accumulator. Firstly, unless you're doing some kind of crazy micro-optimization, just don't ever reuse function inputs in your functions. Ever. You will undoubtedly create unintended side effects that waste countless hours debugging.Consider the case where the array is not an array of primitives. You assign the
initialValue
toarray[0]
if aninitialValue
wasn't defined. Seems innocent enough. In this case though, it's a reference and not a copy. Now on each iteration of theforEach
you're modifying the first element in the input array! Surely that's not what's intended and, especially for your target audience here, you're going to create a very frustrating future experience for them.Now also consider the case where initial value is defined but is not a primitive value. If I was inputting something I wanted to use later in my code it would be unexpectedly changed!
Instead you should take care to create a copy of
array[0]
andinitialValue
when setting the value for your accumulator.You're 100% correct there. I should have assigned
initialValue
to a new variable to make sure the function has no side effects. Bad miss on my part. Thanks for pointing out 😊maybe then update the post as not everyone is going to fully read the comments section :)
Done!
Hey Ryan thank you for this post that I just came across. Do you have your previous solution by any chance so that I can better understand what Jason is pointing out in the comment? Is he saying that in your previous solution you just set " let accum = initialValue" ?
Current
reduce
implementation is wrong - it will handle first item twice if you will not setinitialValue
.Thanks for picking that up! Should be fixed now 😀
I think you can just use
arguments.length
. Cheers!better yet,
typeof initialValue !== 'undefined'
so you avoid touchingarguments
at allinitialValue
can beundefined
yes...but
accum = initialValue
loses its purpose if it is.Hi Ryan! I'm pretty new on my learning journey for JavaScript and would have a question regarding exercise 5.
I generally do get the structure of callbacks, but there is one thing I simply cannot wrap my head around:
Why does the anonymous function within the forEach function require the "item" parameter (see below on line 3).
function mapWith(array, callback) {
const newArr = [];
forEach(array, (item) => {
newArr.push(callback(item));
});
return newArr;
}
Since forEach(array, callback) does execute "callback(array[i])" I simply cannot wrap my head around why this solution would not work:
function mapWith(array, callback) {
let arrNew = [];
forEach(array, () => {
arrNew.push(callback());
});
return arrNew;
}
Maybe you could provide some additional insights? Thank you!
Q: " Since forEach(array, callback) does execute "callback(array[i])" I simply cannot wrap my head around why this solution would not work: "
Answer:
The reason it would not work is because callback(array[i]) will not push the resulting element to the output array, as a result you will get 'undefined' because it hasn't pushed the results into the resulting array. It would simply apply the callback on each item/element. so what we need to do is define another callback method in forEach function.
for(let i=0; i<array.length; i++){
output.push(callback(array[i]))
Basically we want to wrap up this entire functionality into callback of forEach function.
Q: " Why does the anonymous function within the forEach function require the "item" parameter"
forEach(array, (item) => {
newArr.push(callback(item));
});
So for every item that we pass in we want it to push the result of calling the callback with that item into the resulting array. so let's say we have array [1,2,3] the item parameter would call 1 first and apply the callback and push to the resulting array and so on...
There are multiple arguments being passed into multiple parameters and it is kind of confusing but if you step through it line by line using console log statements, it will eventually make sense.
Happy Coding!