1
  • 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
    
Hunter Turner
  • 6,804
  • 11
  • 41
  • 56

4 Answers4

0

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()()();
Ashwin Balamohan
  • 3,303
  • 2
  • 25
  • 47
0

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.

huseyin tugrul buyukisik
  • 11,469
  • 4
  • 45
  • 97
0

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
TheToolBox
  • 272
  • 2
  • 10
0

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.

Community
  • 1
  • 1
takacsmark
  • 3,933
  • 23
  • 26