const els = {
scoreInEl: null, //number <input>
maxInEl: null, //number <input>
percentInEl: null, //number <input>
percentEl: null, //Output
gradeEl: null, //Output
scoreUp: null, //Output
scoreDown: null, //Output
percentOut: null //Output
};
Object.keys(els).reduce((o, k) => (o[k] = document.querySelector("#" + k), o), els); //point of interest
So I have this code here that deals with the .reduce() method and I would like further information about my specific case.
I understand the the Object.keys takes each and every name of the element, such as scoreUp
So if you look at MDN documentation on this it says that you take the last element and the first element and that would be o and k.
Does the o[k] make the scoreUp: null; equal something, and what does it make it equal.
I don't think I understand anything in the query selector, or what the any of the o or k mean in: document.querySelector("#" + k), o,), els) but I do understand that the # means a css id and that the els is the object itself, and in this case would be the initial value.
Doing a console.log(Object.keys...) returns a bunch of confusing information, but from what I can tell its similar to doing something like console.log(document.getElementById()
What I really want from this is an answer to my questions, or a better source than the MDN to explain it
So if you look at MDN documentation on this it says that you take the last element and the first element and that would be o and k.
No, in the code here:
.reduce((o, k) =>
o is the accumulator. It's either:
k is the key being iterated over. Since an initial value is provided, on the first iteration, this is the string 'scoreInEl'. On the second iteration, it's the string 'maxInEl'. Etc.
Since you're returning o at the end of each callback, and that refers to the initial value, the els the accumulator is the same every time.
It might be clearer to remove the confusing comma operator.
Object.keys(els).reduce((o, k) => {
o[k] = document.querySelector("#" + k);
return o;
}, els);
Or, with generic iteration instead of reduce (since the accumulator is the same each time, there's no point in using reduce):
Object.keys(els).forEach((k) => {
els[k] = document.querySelector("#" + k);
});
That's much, much easier to understand. Don't try to be "tricky" by using reduce when it's not appropriate.
Let's go through what you're saying step-by-step first and see whether it's true or false.
I understand the the Object.keys takes each and every name of the element, such as
scoreUp
Yes, Object.keys returns an array of the keys of an object.
So if you look at MDN documentation on this it says that you take the last element and the first element and that would be
oand `k.
No, that's false. In reduce, the callback function's first two arguments are the accumulator (the output object, or what everything in the array is reduced into), and the current item in the array.
Does the
o[k]make thescoreUp: null;equal something, and what does it make it equal.
The o[k] accesses the key/value pair in the object o with the key being the value of k. It doesn't 'make scoreUp: null; equal something', it just is standard property access notation.
You don't need to use reduce here - it's only necessary when you want to manipulate (usually group) items of an array. This is modifying each key/value pair in an object. For that, I would recommend either a loop over Object.keys (note looping, not using reduce):
Object.keys(els).forEach(k => els[k] = document.querySelector("#" + k));
Or a for-in loop which will effectively do the same thing.
for (const k in els) {
els[k] = document.querySelector("#" + k);
}