Reputation: 1
I know that this doesn't make complete sense to write code this way, but this is testing my understanding of the scope chain and block scopes:
function mygreeting(){
var myvar = "init"
if(myvar === "init"){
let blockScoped = "hello";
var mygreet = function() {
console.log(blockScoped);
}
return mygreet;
}
}
mygreeting()(); //outputs 'hello'
I understand that this is a closure and the inner function will keep a reference to its outer environment, but really what I'm trying to figure out is why a function-scoped function expression is able to find a block-scoped variable (blockScoped) in its closure. Is it storing block scoped variables in its scope chain, and does a scope chain for a function expression depend on how the expression is declared (with let or var?) Thanks!
Upvotes: 0
Views: 514
Reputation: 1487
A function can access all the variables in its scope and scopes that encapsulate it. Because myVar
is within the same scope when mygreet
is declared, it can "see" it.
An analogy that helped it click for me was imaging nested scopes as a hole. When you're in the hole, no matter how deep (nested) it is, you can always look up and see the sky, but looking down you just see dirt. Similarly, any function can access the variables declared in its scope (the bottom of the hole) + any nested scopes (the walls of the hole) + the global scope (the sky).
var one = 1
function foo() {
var two = 2
function foobar() {
var three = 3
console.log(one) // works
console.log(two) // works
console.log(three) // works
console.log(four) // doesn't
}
}
function bar() {
var four = 4
console.log(one) // works
console.log(two) // doesn't work
console.log(three) // doesn't work
console.log(four) // works
}
As for let
vs var
, the only difference is let
treats its block like a scope. But the same rules still apply. A function declared in that block (that could "see" the variable at the point of declaration) will be able to reference that variable at execution.
Upvotes: 1