Higher order function Javascript - javascript

I am new to Javascript, and sturdying about the concept of higher order function, and using function as parameters.
I got two examples of code from online, and I do not understand what is going to happen.
First one, output will be 0, and I could not print the time of t1 and t2 ( I tried console.log(t1), but it became reference error). I wonder why it became 0.
Also, I don't get how funcParameter() that is inside of functionbody is working for the function, though I know funcparameter() is callback function, and which is addOneToOne().
Second one, output will be 3. but how can it be 3 even though, I haven't put parameter into addTwo()? If I have not put anything in parameter, num will be automatically 0 or undefined?
I am sorry for many questions, but I really appreciate if you could help me out.
//1st code
const timeFuncRuntime = funcParameter => {
let t1 = Date.now();//
funcParameter();
let t2 = Date.now();//
return t2 - t1;
}
const addOneToOne = () => 1 + 1;
timeFuncRuntime(addOneToOne);
console.log(timeFuncRuntime(addOneToOne))//0
//2nd code
const addTwo = num => num + 2;
const checkConsistentOutput = (func, val) => {
let firsttry = func(val);
let secondtry = func(val);
if(firsttry === secondtry){
return firsttry;
} else {
return 'This function returned inconsistent results';
}
};
checkConsistentOutput(addTwo,1)
console.log(checkConsistentOutput(addTwo,1))//3

1: The scope of the t1 variable is limited to the function block. You can read more about variables scope here
2: You are using val as function parameter, and the value of val is 1.
1 + 2 = 3
The 1 is in this line:
checkConsistentOutput(addTwo,1)

First one, output will be 0, and I could not print the time of t1 and t2 ( I tried console.log(t1), but it became reference error). I wonder why it became 0.
Because zero milliseconds passed between the first call to the callback and the second. Date.now() works in milliseconds. The call probably took microseconds at most.
You couldn't access t1 or t2 because they're local variables in the timeFuncRuntime function, so you can't access those variables outside the timeFuncRuntime function, only inside it.
Also, I don't get how funcParameter() that is inside of functionbody is working for the function, though I know funcparameter() is callback function, and which is addOneToOne().
Functions are objects in JavaScript. When you do timeFuncRuntime(addOneToOne), you're passing a reference to the function into timeFuncRuntime which it receives as the value of the funcParameter parameter. So when that code does funcParameter(), it's calling addOneToOne.
Second one, output will be 3. but how can it be 3 even though, I haven't put parameter into addTwo()?
Because checkConsistentOutput did it. When you do console.log(checkConsistentOutput(addTwo,1)), you're passing a reference to addTwo and the number 1 into checkConsistentOutput. It receives them as its func and val parameters. So when it does func(val), it's calling addTwo with the value 1. It gets the result in the firsttry variable, then does the call again and gets the result in secondtry, and since they match, it returns the value of firsttry, which is 3.

Second one, output will be 3. but how can it be 3 even though, I haven't put parameter into addTwo()?
You copy the function stored in addTwo as the first argument to checkConsistentOutput where it gets assigned to func. Then you call the function here — let firsttry = func(val); — and here — let secondtry = func(val);

Related

Javascript - Higher order functions, callbacks, returning, scope chain - I could use some assistance, see example pleas

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
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.

JavaScript - How to modify 'variable' inside function so that it does not revert to original value after function termination?

I have a script like this:
function changeValue(x){
x = 30;
}
let a = 3;
changeValue(a);
console.log(a);
The above code outputs 3, but the expected output is 30. Now I'm aware why this is happening, but how do I modify my code so that the changes made do not revert after the changeValue function ends?
I have read that there are no explicit pointers in JS and I don't want to alter the value using the global variable name or by using the object approach. Is there any other way to solve the problem?
Thank you
The best way would be to use return, because x isn't an object, it's just a variable. It is discarded after the function.
Using Return:
function changeValue(x){
return 30;
}
let a = changeValue(3);
changeValue(a);
console.log("Output Is:", a);
In JavaScript, all primitive types (integers, floats, etc) are passed by value, so as other people said, for your specific use case, it's better to return the value like this:
function returnValue(x) {
return x * 10
}
let a = 3;
a = returnValue(a);
console.log(a);
However, if you really want to change the argument and NOT return, you need to do it with pass by reference. As I said above, it's not possible with primitive data types but is possible with objects:
function changeValue(x) {
x.value = x.value * 10;
}
let a = { value: 3 };
changeValue(a);
console.log(a.value);

What do I need a return statement for in JavaScript?

I'm trying to wrap my head around the return statement but I can't see a reason why I should use one. My code works just fine without using one...
In both examples my console prints out 10 not matter if I use return or not.
Without return:
var sum = 5;
function myFunction() {
sum += 5;
}
myFunction();
console.log(sum);
With return:
var sum = 5;
function myFunction() {
return sum += 5;
}
myFunction();
console.log(sum);
By default, functions return the value undefined. If you want the function to return some other value, you need to have a return statement.
You may also use a return statement to halt execution of the function based on some logic, again returning a value that has some meaning or just undefined.
In the first example in the OP, the function is called and the return value is not used for anything, so it doesn't matter what the return value is and a return statement isn't necessary.
In another scenario, the return value might be important, e.g. a function that generates an integer random number between 0 and 10:
function getRandomInteger(){
return Math.floor(Math.random() * 11);
}
function showRandomNumber() {
document.getElementById('s0').textContent = getRandomInteger();
}
<button onclick="showRandomNumber()">Show random number</button>
<span id="s0"></span>
In the above, the getRandomInteger function needs to return a specific value, so it uses a return statement. The showRandomNumber function just displays the random number, so it doesn't need a return statement as the caller (the listener on the button) doesn't care what the return value is.
Here is what is happening with your example:
var sum = 5; //Sets the sum to =5
function myFunction() {
return sum += 5; // += reassigns the global (sum) to 10
}
myFunction();
console.log(sum);
A better example would be this:
sum = 5;
function myFunction() {
var sumOther = sum + 5;
return sumOther;
}
console.log(“sum:” + sum); // 5
console.log(“myFunction:” + myFunction()); // 10
This is how you would get the run of the function and not the global variable ‘sum’
This is because you use (global) variable declared outside the function (function modify it directly so there is no need to return value). However it is not good way of write functions because they are less reusable because they need proper global context to be used. Better is to use something like this:
function myFunction(num) {
return num += 5;
}
var sum = 5;
var result = myFunction(5) ;
console.log(result); // -> 10
this function can be easily used ind different context because it have parameter num and works only on it (function uses only values declared inside its declaration and body)
The trick in your case a is scope of a function. In both cases variable sum is defined in global scope. When you calling the function, it goes through the following steps:
Look whether var sum is defined in current step Since it not defined
inside the function, go one step over and take a look into outer
scope. Yes, it is defined here, start using it.
Perform calculation.
You are using incremental operator sum += 5 so actually it can be
written as sum = sum + 5. If you will look into second case,
you'll notice that variable have increased value now. And since that
variable is taken from global scope, your function just mutates it.
NOTE: At this point no matter whether you are returning something
from function or not. Your function just mutated outer variable.
The last step - exit from function. As I said earlier, return value
matters only if you want to use result of function call directly,
for instance: var result = myFunction()

Concept about anonymous function and invoke in javascript [duplicate]

This question already has answers here:
How do JavaScript closures work?
(86 answers)
Closed 4 years ago.
Now I have to solve a exercise in the exercise from freecodecamp.
The outcome are expected as follows:
addTogether(2, 3) should return 5.
addTogether(2)(3) should return 5.
addTogether("This is sth") should return undefined.
addTogether(2, "3") should return undefined.
addTogether(2)([3]) should return undefined.
And by referring to some suggested solutions, one of the solutions is like:
function add(){
var args= [].slice.call(arguments);
if (!args.every(function(argument){return typeof argument === 'number';})){
return undefined;
}
if(args.length === 2){
return args[0] + args[1];
} else {
var a = args[0];
var addOne = function(b){
return add(a,b);
};
return addOne;
}
return false
}
add(2)(3)
In here, I am not really sure, why in the variable addOne, the anonymous function will successfully capture the the value in the second brackets, after calling the first value before?
I seek for the information about JavaScript function invocation, but still do not 100% sure why...
Edited:
With the features of closure, because I have already extracted the first parentheses, the next closure i.e the function, will automatically take the second input? And in this case, if I want to do addTogether(2)(3)(4)(5) , then I can do that by creating closures within different parentheses e.g
var a = args[0];
var addOne = function(b){
var addTwo = function(c){
var addThree = function(d){
return a+b+c+d;
}
}
};
Do I understand in the correct sense?
In here, I am not really sure, why in the variable addOne, the
anonymous function will successfully capture the the value in the
second brackets, after calling the first value before?
Because, when you say, addTogether(2), it means you're calling a function and passing it an integer 2, and when you say addTogether(2)(3), it means, you're calling a function and passing it an integer 2, which is then returning a function, to which you're passing the integer 3.
So, when the code says return addOne, it is returning the function which is called with the second parentheses, (3), so addTogether gets the value 2 and the return of addTogether, which is addOne gets the value 3.

understanding the increment operator within in return function

I am trying to understand a small piece of code
for the first i it prints 1 since The value of ++i is the value of i after the increment.
but not sure why second and third prints 2 and 3 since it conflicts (The value i++ is the value of i before the increment)
in the end why it prints 4
can you guys tell me why its doing like this
//What is i?
var i=0;
var add = function(){
++i;
console.log(i); //output--->1
return function(){
i++;
console.log(i); //output--->2
///not sure why it happens like this
return function(){
i++;
console.log(i); //output--->3
///not sure why it happens like this
add();
}
}
};
add()()();
//what does this method do here
i definitely appears to be doing what one would normally expect. I believe you may have a bit of confusion as to the difference in the preincrement and postincrement operators. ++i returns the incremented value of i, while i++ returns the original value of i before incrementing it. That being said, they both end up incrementing i. The following code shows this:
var i = 0;
console.log(++i);// prints '1'
console.log(i); // also prints '1'
var j = 0;
console.log(j++);// prints '0' because that was the original value
console.log(j); // prints '1' because j still got incremented in the end
It looks like you've misunderstood the difference between ++i and i++. The issue concerns operator precedence on the SAME statement.
If you are always doing the console.log() on the next line, you won't see a difference.
Try something like this:
var x = 0;
console.log(x); // => 0
console.log(++x); // => 1 (increment happened before the console.log)
console.log(x); // => still 1 (nothing changed)
var x = 0; // let's start again
console.log(x); // => 0
console.log(x++); // => still 0 (increment happened after the console.log)
console.log(x); // => 1
Now let's also consider the execution of the functions that are returned (see the comments):
var i=0;
var add = function(){
++i;
console.log(i); //output--->1 - from add() and also output--->4 from the final call to add() at the end of the function
return function(){
i++;
console.log(i); //output--->2 - from add()()
///not sure why it happens like this
return function(){
i++;
console.log(i); //output--->3 - from add()()()
///not sure why it happens like this
add(); // calls add() one more time (which only executes the first ++i and the first console log)
}
}
};
add()()();
add()
just returns a function by incrementing i by 1
()
executes that function so it returns another function after increment.
()
executes that function so you have another function after increment and that function calls add() which increments again and returns another function.
i is incremented 4 times, function returns function 4 times but last function is not executed, it is just returned to body.
add() ----> function (){ i is 1 now., return ... }
add()() ----> function (){ i is 2 now., return ...}
add()()() ----> function (){ i is 3 now, function(){i is 4 now, return...} }
i++ or ++i is irrelevant unless it is in an chain of instructions of a statement and may become undefined behaviour if you use it multiple times in same statement.
If you had called it as add()()() in innermost function, instead of add(), then it would be infinitely recursive.
Instructions in functions are issued(even executed and finished unless they are event based) serially.
Let's break it down with some enhanced logging.
First of all let's talk about the big picture. The sample code you provided is an example of currying. It's a functional programming technique, it means, that you break down a function that takes multiple arguments into a series of functions. You can read more about currying on stackoverflow, Wikipedia, or just google it.
This means that your function is a series of functions. I changed your example to an equivalent code that invokes each function one by one.
// The definition of the add function
var add = function(){
console.log('first function in the sequence');
++i;
console.log('i = ', i); //output--->1
return function(){
console.log('second function in the sequence');
i++;
console.log('i =', i); //output--->2
return function(){
console.log('third function in the sequence');
i++;
console.log('i =', i); //output--->3
console.log(typeof(add()));
}
}
};
// This is how you invoke the 'add' sequence one by one
var i=0;
console.log('\n***** calling the sequence one by one \n')
const f2 = add()
console.log(typeof(f2))
const f3 = f2()
console.log(typeof(f3))
f3()
First we define the add function, it's the same as yours. It's in fact the sequence of three functions.
The first function is invoked by calling add() itself.
The first function increments i by 1. (i has the initial value
of 0 defined by the line that says var i=0;. )
Then the function logs out the value of i, which is 1 at this point.
Then it returns a function ( the second function).
This means that if you just invoke add like add() you'll get a function back and the value of i will be 1.
In order to prove this I added the lines in the above code that say:
const f2 = add()
console.log(typeof(f2))
The console output at this point is
***** calling the sequence one by one
first function in the sequence
i = 1
function
i=1 and the type of f2 in the code is function. The return value of add() is a function.
Lets's invoke f2 and assign its return value to f3 on these lines
const f3 = f2()
console.log(typeof(f3))
This produces the following output:
second function in the sequence
i = 2
function
The second function was invoked and changed the value of i. It returned another function, f3. It's time we invoke the third function.
f3()
f3 does not have a return value, you can see it in the code that it does not return anything. The console output is this:
third function in the sequence
i = 3
first function in the sequence
i = 4
function
You see that we printed out that we are in the third function, incremented i and logged its value, which is 3.
Then if you look at the code what's happening is that we call add() again inside the third function. So the first function will run again. It increments i and logs out its value.
I logged out the type of add() in f3 and you see that it's a function. And this is the end of the sequence add() returned a function to f3 and we do not do anything more with it there.
Now let's return to your code.
The main difference is that you are not invoking the functions one by one, you invoke them on one line. This one.
add()()()
You can immediately invoke the returned functions like this. This produces the same output:
***** calling the full sequence
first function in the sequence
i = 1
second function in the sequence
i = 2
third function in the sequence
i = 3
first function in the sequence
i = 4
function
P.S. the order of ++ in i++ and ++i does not matter to you, because you log the value of i later, when its already incremented.

Categories