Help Understanding Scope: Outer and Inner

I’m having a difficult time understanding how scope and assignment works. For example:

Example 1:

var fn;

function foo() {
    var a = 2;

        function baz() {
            console.log( a );
        }

fn = baz; 

}

function bar() {
    fn(); 
}

foo();

bar(); // 2

I thought that when function bar is called, fn would return undefined because the assignment of baz to fn happens within the scope of foo. I was under the assumption that fn=baz would only be true within the scope of foo.

I think I’ve gotten things a bit whacky in my head.

So in regards to variable declaration, if a variable is declared within an inner scope, I understand that the variable cannot be reached in the outer scope. For example:

Example 2:

function hideA( ){
    var a = 2;
}

console.log(a); // this would return referenceError; makes sense

But I’m a bit confused in regards to how scope works when assigning a value to a variable because this doesn’t seem to work:

Example 3

var a=0;

function empty(){
    a=2;
}

console.log(a); // returns 0

I thought that Example 3 and Example 1 would have behaved similarly, but in example 1, fn takes the assignment of baz within the scope of foo, while in example 3 a does not take the assignment of 2 within the scope of empty.

Any help would be appreciated!

Thanks guys :slight_smile:

In example 3 you only defined a function empty(), but never invoked it. Check what happens when you actually invoke empty(), (in example 1 foo() is invoked before bar())

1 Like

Thanks guys! I understand the difference between Example 1 and Example 3 now. Once I invoke empty, I am able to assign the value 2 to the global variable a.

@MarkoN95 Thank you for explaining the 3 concepts regarding scope! Lexical scope is a bit confusing but I think I understand it. The function init( ) looks to it’s own scope first rather than the global scope even though it was invoked in the global scope. Is this what you were referring to?

In regards to the scope chain, a good metaphor that I’ve heard is the building metaphor. Starting at the bottom or most inner scope, we work our way up to the building to find the variable that we need. Once we get to the roof, we can’t go any higher and thus a referenceError is thrown!

Thanks a lot guys, this helped a lot !

Hey @marzelin & @MarkoN95 can I get your guys’ help on checking my understanding of lexical scope one more time? Let me know if I’m misunderstanding anything!

So I have a few more examples that I’d like to explore:

Example 1

var a;

function foo ( ) {
    a = 3;
    function bar ( ) { 
        var b = 7;
    }
}

foo ( ); //invoking foo assigns 3 to global variable a

console.log(a); // prints 3

console.log(b); //ReferenceError, is there any way to reach b at the global scope?

When foo is invoked the engine looks for the variable foo in the scope that it was declared, which in this case is the global scope. Once the engine finds foo, foo is invoked. Within foo, the engine looks for a variable a, which it finds in the global scope, and assigns the value 3 to the global variable a. The function console.log(a) then looks for the variable a in the global scope which now has the value 3 and prints 3.

The function console.log(b) looks for the variable b, but cannot find it in the global scope and thus throws a referenceError.

To reach the variable b in function bar, I would have to return the variable b to a new variable (let’s call it c) once the function bar is called.

Example 2

var a;
var c;

function foo ( ) {
    a = 3;
    function bar ( ) { 
        var b = 7;
            return b;
    }
    c = bar( ); // passes the value of 7 to c
}

foo ( ); //invoking foo assigns 3 to global variable a

console.log(a); // prints 3

console.log(c); // prints 7

Is there a way to reach the variable b without declaring a new variable c?

To reach the variable b in function bar, I would have to return the variable b to a new variable (let’s call it c) once the function bar is called.

You cannot return a variable, you can return a value stored in that variable. There’s no way to reach variable b outside of bar(), but you can pass value stored in b wherever you want.

Thanks guys! I think I got it :slight_smile: