Ahmed Zoghayyer Ahmed Zoghayyer - 18 days ago 7
Javascript Question

Does the callback function create a new scope in javascript

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

Answer

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());

Comments