Plz help in this code


#1

I was just experimenting in order to understand scopes and closures. I wrote the code below and expected it to return the value 10 but instead it returns [Function: scope2].

I thought I would invoke scope1 which will invoke scope2 which will invoke scope3 which will access all the variables declared in the enclosing functions along with the global variable and return their sum.

I’m unable to see where I’m going wrong. Plz Help

var globalscope = 4
function scope1() {
    var one = 1
    return function scope2() {
        var two = 2
        return function scope3() {
            var three = 3
          console.log(one + two + three + globalscope)
        }
    }
}

console.log(scope1())


#2

Consider the following:

var globalscope = 4;
function scope1() {
    var one = 1;
    return function scope2() {
        var two = 2;
        return function scope3() {
            var three = 3;
            return one + two + three + globalscope;
        };
    };
}

console.log(scope1()()());    // -> 10

#3

I wrote this code and it worked.

var globalscope = 4
function scope1() {
    var one = 1
  function scope2() {
        var two = 2
    function scope3() { 
            var three = 3
            console.log(three + two + one + globalscope) 
            }
        return scope3() 
        }
        return scope2() 
    }

scope1()

But I did not understand why do we have to write scope1()()() with 3 pairs (2 extra) of parenthesis in the previous code for it to work?
I thought that scope1() will return scope2() which will return scope3()


#4

scope2 needs to be invoked, however its return is a function that must also be invoked to get at the return of scope3…

scope1 => scope2 => scope3

The first function returns the second which returns the third. We must invoke all of them to get to the final return.


#5
10
undefined

in white.

?


#6

I thought that returning a function will automatically invoke it but you have to define the function within the function and then invoke it afterwards.
Sorry I did not understand your question above…


#7

What did the output of your function look like? Was it in white text?


#8

Yes it displayed 10 in white when I ran my code.


#9

Did it also display undefined in white?


#10

No it did not. Only 10 in white.

I also tried the code below (invoking the nested functions immediately because u said that functions need to be invoked too) but it throws error I don’t know why:

var globalscope = 4
(function scope1() {
    var one = 1
    (function scope2() {
        var two = 2
        (function scope3() { 
            var three = 3
            console.log(three + two + one + globalscope) 
            }())
    }())
}())


#11

You are invoking four functions when there are only three.


#12

How? I thought console.log has to be run in order to print out the answer…


#13

I jumped too quick. Didn’t see all the closures. My bad. You see the similarity with my original reply?


#14

I see it and I tried invoking all the functions immediately but it returns NaN and then TypeError: 2 is not a function. (In '2', '2' is 2) but it doesn’t matter because I will now first define the functions and invoke them later instead of invoking them immediately by putting parens after they end because I’m not clear how it works out.


#15

That is an admission that shows interest. Let’s explore it…

(
)()

Strictly speaking, this is an IIFE.


#16

Yeah I want to go deep in this.

So how can we apply it in this code?


#17
(() => console.log('foobar'))()

#18

The code I wrote above (using IIFE) works!!!
It’s just that it kept saying ‘Bad invocation’ (I didn’t know why) until I put semicolon after the variable declarations.

I know how it works but because of a minor mistake it didn’t work.

So the code below will print out 10!

var globalscope = 4;
(function scope1() {
    var one = 1;
    (function scope2() {
        var two = 2;
        (function scope3() { 
            var three = 3
            console.log(three + two + one + globalscope)
            }())
    }())
}())

It’s the same code u wrote in the first reply but with IIFE.

But I don’t understand why do I have to put the semicolons after I declare the variables?

I thought that you can usually omit the semicolon between two statements if those statements are written on separate lines. Is it that Javascript cannot parse the code without semicolons?

This one also works:

var globalscope = 4
function scope1() {
    var one = 1
    return (function scope2() {
        var two = 2
        return (function scope3() {
            var three = 3
            return one + two + three + globalscope;
        }())
    }())
} 

scope1() //just invoke scope1 which will invoke all the nested functions automatically (what I was trying in the first place)


#19

JavaScript has no problem parsing code without end of statement tokens. They are part of the syntax, just the same, and best practice until such time as ECMA decides to do away with them, altogether.

If we look at another language, Python, we never see semi-colons, except when lines are combined. That should give a clue as to why they are needed. Minifying code removes white space (which includes line breaks). That is when JS chokes on parsing. It cannot tell where one statement ends, and the next begins.


#20

Ok. Thank you very much :+1: