1
function hello() {
  var result = [];
  var str = 'I am here';
   function inner() {
    var result = [];
     for (var i=0;i<10;i++) {
        result.push(i);
     }
     return result;
   }
}

in the code above when I called the function hello(), the return value was an empty [], also it did not console.log the str from the inner function. However, in the below code set I have used a call back function:

 function forEach(cb) {
   for(var i =0;i<10;i++) {
    cb(i);
   }
}

function hello() {
   var result = [];
   var str = 'I am here';
   forEach(function(num) {
    console.log(str);
     result.push(num);
   }); 
   return result;
}

the question is why both functions reacted, and gave a different output? Note; in both codes there was an inner function which supposed to create a new scope that can access the outer scope ? Does anyone have a good explanation for this issue ? Thanks

2
  • In the first example, of course the return value is an empty array - because you never populate it... Commented Nov 15, 2016 at 5:02
  • You never called the function named inner. Functions don't run unless you call them. You could try var result = inner(); return result;. Commented Nov 15, 2016 at 5:06

2 Answers 2

2

In the first code block, inner is a new function that is declared inside of hello. It does not execute because you do not call it. It does create a new child scope inside of hello when it is called. But, since hello() doesn't actually return anything and doesn't call inner(), you get undefined when you call hello(). You could fix that by changing to this (you can run this snippet to see the return value):

function hello() {
    var str = 'I am here';

    // declare inner
    function inner() {
        var result = [];
        for (var i = 0; i < 10; i++) {
            result.push(i);
        }
        return result;
    }

    // now call inner() and return its result
    return inner();
}

console.log(hello());

Functions declared inside other functions do create a new scope. Every function declaration and corresponding call in Javascript creates a new scope. If the function is inside another function, then the code inside that inner function has access to both its local scope and to the parent scope and this can nest as deep as your nested function declarations go.

the question is why both functions reacted, and gave a different output? Note; in both codes there was an inner function which supposed to create a new scope that can access the outer scope ? Does anyone have a good explanation for this issue ? Thanks

In the first example, you never called the inner function so it never executed.


In the second example, you pass an inline, anonymous function reference as a function argument to your forEach() function. When that forEach() function executes, it calls your callback function with the line of code cb(i) so that's how your callback function is getting called in the second example. forEach() calls it for you.

Also, in the second example, the locally declared callback function is accessing the parent scope and modifying the result array (which is perfectly allowable). In your first code example, you are declared a new result variable in the inner function scope and then returning that. You are not accessing the parent result variable. When you declare a local variable with the same name as a variable in the parent scope, the local variable overrides the parent variable (essentially hiding the parent variable) and any references to that variable in the local scope only access the local variable.

You could have written the first code example to use a parent scoped result variable like this:

function hello() {
    var result = [];
    var str = 'I am here';

    // declare inner
    function inner() {
        for (var i = 0; i < 10; i++) {
            result.push(i);
        }
        return result;
    }

    // now call inner() and return result
    inner();
    return result;
}

console.log(hello());

Sign up to request clarification or add additional context in comments.

3 Comments

you are right, I got this point, but why does the second scenario when I used the callback it did output the result + console.log the (str) the out without calling the callback function?
@AhmedZoghayyer - forEach() called the callback function for you with the line cb(i). You passed the inline anonymous function as a function argument to forEach() and then when you executed that function, it called that function for you.
@AhmedZoghayyer - I added a bunch more explanation to my answer about local and parent scoping.
1

You have confused function declaration and calling.

Declaring a function can be done in multiple ways:

function myNewFunction() {}

Now this function exists in the current scope, but will not execute unless called.

You can call the function like this. Now your function will get executed.

myNewFunction();

Functions and their scopes can be compared to variables. Functions defined inside another function can only be accessed from inside the parent function. Let me give you an example.

    function myMegaFunction() {
        console.log("in mega");
        function mySmallFunction() {
            console.log("in small");
        }
    }

    myMegaFunction(); 

This will only print - 'in mega'. If you call mySmallFunction() inside of myMegaFunction then both lines will get printed.


Now let's take a more complex scenario like this:

    function myMegaFunction() {
        console.log("in mega");
        var str = "car";
        var result = function mySmallFunction() {
            console.log("in a small", str);
        }
        return result;
    }
        
    var resultingFunction = myMegaFunction();
    resultingFunction();

This will first print the following: in mega in a small car

So essentially, this is functions being passed around like variables. They can be executed later on too.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.