Reputation: 29
I really could use some help in understanding how this all works. Please bare with since I am a disabled learner who sometimes can not grasp basic concepts like other people. I have tried looking it up, searching Google, and Chatgpt for answers, but I seem to have a problem with closure I believe it called.
function eitherCallback(callback1, callback2) {
return num => callback1(num) || callback2(num)
}
function filterArray(array, callback) {
const newArray = [];
for (let i = 0; i < array.length; i += 1) {
if (callback(array[i],i, array)) newArray.push(array[i]);
}
return newArray;
}
const arrOfNums = [10, 35, 105, 9];
const integerSquareRoot = n => Math.sqrt(n) % 1 === 0;
const over100 = n => n > 100;
const intSqRtOrOver100 = eitherCallback(integerSquareRoot, over100);
console.log(filterArray(arrOfNums, intSqRtOrOver100)); // should log: [105, 9]
So, what I do not understand is the value/values being sent to eitherCallback and how the arguments work.
So first filterArray has 2 parameters, arrOfNums and intSqRtOrOver100 So I was able to figure out a lot of problems like that intSqRtOrOver100 is a function just a variable, a function expression, however, that is not hoisted so filterArray would go first.
arrOfNums would be the array, and intSqRtOrOver100 would invoke intSqRtOrOver100 the function,
First Question/Issue: intSqRtOrOver100 is the function calling eitherCallback(integerSquareRoot, over100);? So intSqRtOrOver100 would take not arguments, however, filterArray is passing it iteration of referenced index in the array passing the value to the callback which is intSqRtOrOver100. So it would be 10 passed to intSqRtOrOver100?
Yet, there are 3 arguments being sent to intSqRtOrOver100?
Second Question/Issue: When intSqRtOrOver100 is invoked by the callback, intSqRtOrOver100 is calling eitherCallback with two parameters, so the two parameters are functions passed in as arguments which I understand, however, when intSqRtOrOver100 is invoked, those two parameters are not being passed arguments since they are functions yet, somehow it is being sent an element from the array?
Third Question/Issue: So eitherCallback has two functions and is created by intSqRtOrOver100 invoked, I am passing an element from the array and somehow 3 things from filterArray? Also, no arguments are being sent since they are functions, then inside of the function I am using a return function I guess the name if "num", however, how can Callback1(num) exist? Nothing is declared as num except itself. Changing the parameter name defaults to an error. I understand the about it being true and condition of it but, not how Callback1 is being called with "num" itself and how come the index, plus two others are being passed into it yet, I can not access the newArray, i or the array inside of eitherCallback, yet shouldn't filterArray be the higher order function and since it's the parent, should I be able to access it values?
Please, I have really tried for over 8 hours to understand this. I do understand some of it, but, since this is my first time asking for help, I was nervous about asking and hope I got it to come out right. If you could explain it to me simply and slowly because I am not quite understanding and I really want to learn this concept if possible. Thank you so much for your time.
Searched:
Google Stackoverflow Videos ChatGPT Chegg Various Websites Digital Ocean Youtube
Upvotes: 1
Views: 85
Reputation: 4600
I'll give a little try to explain. The core that you are missing is the thing that is happening here:
function eitherCallback(callback1, callback2) {
return num => callback1(num) || callback2(num);
}
This function takes 2 parameters, callback1
and callback2
, which supposed to be a functions. And returns a function which takes 1 argument named (num) and executes 2 closure captured functions (callback1
and callback2
) with that num
. Basically, it is an alternative to this:
function eitherCallback(callback1, callback2) {
function fn(num) {
return callback1(num) || callback2(num);
}
return fn;
}
Now about this section:
const integerSquareRoot = n => Math.sqrt(n) % 1 === 0;
const over100 = n => n > 100;
const intSqRtOrOver100 = eitherCallback(integerSquareRoot, over100);
Here you are declaring 2 arrow functions, integerSquareRoot
and over100
. They both are functions that take 1 argument. Equivalent:
function integerSquareRoot(n) {
return Math.sqrt(n) % 1 === 0;
}
function over100(n) {
return n > 100;
}
const intSqRtOrOver100 = eitherCallback(integerSquareRoot, over100);
Here you are calling eitherCallback
with 2 arguments. Basically you are passing the references to those functions, and they are "wired" now, closure captured.
So, now, intSqRtOrOver100
is the fn
returned from eitherCallback
, which has integerSquareRoot
as callback1
and over100
as callback2
. And it does take 1 argument, which is (num).
Now about this section:
function filterArray(array, callback) {
const newArray = [];
for (let i = 0; i < array.length; i += 1) {
if (callback(array[i],i, array)) newArray.push(array[i]);
}
return newArray;
}
Especially the callback(array[i], i, array)
- why it is called with 3 parameters - just conventionally, I guess, inspired by Array.filter(), for example, which also accept a callback function with 3 parameters. But still, you can pass a callback function that takes 1 parameter only and it is absolutelly normal. You can easilly check what is passed to your callback by:
function eitherCallback(callback1, callback2) {
return (num) => {
console.log(num);
return callback1(num) || callback2(num);
};
}
or
function eitherCallback(callback1, callback2) {
return (num, index, array) => {
console.log(num, index, array);
return callback1(num) || callback2(num);
};
}
So, to summarize:
Q1 and Q2 - intSqRtOrOver100
is the function that takes 1 parameter (num) and is internally wired to integerSquareRoot
and over100
via closure.
Q3 You are passing 3 parameters to intSqRtOrOver100
hovewer intSqRtOrOver100
utilizes only 1st parameter, rest ones are ignored.
Upvotes: 1