Step by step we are on the way to understand JavaScript Engine better. We have seen how JavaScript creates, executes and navigates through the world of script. We were exercising our imagination last two posts. This time we need to try harder 💪
If you need refresher on Execution Context and Call Stack consider reading last two posts 😉
Imagine Execution Context and Hoisting
We already know that JavaScript function is a world. The tiny world inside big Global world. Today, we are going to create the first city. The "Function City".
Welcome to Function City! 🌃
Imagination ON 🌈
Each city need to have buildings and houses (it's same thing, aha). Every city has items and goods for citizens too, so that they can use it - buy, sell, cook, wear, etc. Buildings can be goods too, like a private property. Citizens use buildings too.
City needs a Mayor. And Mayor of Function City is beloved by all! She is a very kind and generous person. City has it's own assets and goods. These goods are public and free for everyone. Every household have access to them.
As in any modern society everyone has their private goods, which citizens keep inside their houses. Some, on the other hand, have some priviliges and can change the goods available for citizens.
Of course, city is not complete without helper buildings, so that citizens can interact with them. Restaurants, Cinemas, Shops, etc. All this buildings offer you their services and are functioning in the city.
By the way, your sister Julia works in one of those. She works at Translation Services Agency. How this agency works you wonder? So you pass them your documents (goods), they process it and return result back to you.
There are so many goods in the city which are public and Agency has access to them. The Agency can actually change and process this documents if needed.
So, looks like a nice city right? It is. But a little weird too. Mayor can change the meaning of the goods. What? What does it mean? Let's say, today you had a car, then Mayor has reassigned another item to your car and poof....now you have a carrot.
There are set of words, which were given by the creator of this whole world. Those words can't be changed. No one can reassign them. Also, citizens do have some common sense. When they were building the city, they made a list of constant words which cannot be reassigned too. Whole city depends on these words.
Imagination OFF
Phew...this one was a hard abstraction to make up. I've tried to make it simple, yet meaningful.
Any constructions like building are representing functions. Do you remember the small world in the big one thing? Just like your own house is a small world in the big world. The goods are values. Names are variable names. Any item can be reassigned to any name, except for those rules.
Scope
Before EcmaSript 2015 (ES6) only var
was available and scopes were a real issue. Variable declared with var
would be accessible everywhere within the script and could be redeclared. ES6 introduced let
and const
variable declarations. They have block (local) scope and var
was almost completely replaced.
So what is Scope? 🤔
Our scripts are full of functions. Functions as we know can take arguments, they have their own local Execution Context, they can have own local variables. This - is Scope. The Scope of the function. It is like indoors of the buildings that we have imagined. Private. Secure. You can interact with outer world from inside. But outer world cannot interact with you.
Functions can have functions inside and those will follow the same rules. Let's look at example:
function example (a, b) {
console.log(a);
function inside () {
let c = 'Hello';
console.log(c + ' world!');
console.log(b);
}
inside();
}
Looks confusing right? Try to remember all that we have learned so far. What will happen first? Global Execution Context. At Creation Phase all the code will be read by JavaScript Engine and stored into memory. function example()
is completely stored into memory and ready to be invoked. Creation Phase is over at this point. Execution Phase starts. Execution Phase will go through the code and once it reached example()
it will invoke it. What's next?
Once function example()
is invoked the Function Execution Context will start. If you remember, it's almost same as Global. The arguments object will be created and store our a
and b
arguments. console.log(a)
is also a function and will be stored into memory. function inside()
will be stored too. Then it's time for Execution Phase again. console.log(a)
will be invoked and print statement in console. Then once it will reach inside()
again the same thing is going to happen. Function Execution Context will start.
Hope when you look at this step by step it became much easier to understand. Every Execution Context can have access to the parent Execution Context variables. But parent doesn't have access to it's child ones. Parent Execution Context can only pass data as arguments.
Example output
example('Yo!', 'You are the best =)');
> 'Yo!'
> 'Hello world!'
> 'You are the best =)'
Can you trace what happen? What will happen in this case then?
function example (a, b) {
console.log(a);
b = 'See you around =)';
console.log(c);
function inside () {
let c = 'Hello';
console.log(c + ' world!');
console.log(b);
}
inside();
}
Try to use your imagination. Try to imagine those scopes, those locked houses with private data. Can somebody access your goods inside your house?
I think you have managed it. But what if we declare c
before and then try to declare it again with var
?
function example (a, b) {
console.log(a);
var c = 'Hehehe I am nasty var';
b = 'See you around =)';
function inside () {
var c = 'Hello';
console.log(c + ' world!');
console.log(b);
}
console.log(c);
inside();
}
Are we those privileged citizens who can change c
on their will? Yes we are. var
declaration is happening in Global Scope (available everywhere in the program) or in the Function Scope (available only inside the function and other inner functions). var
can be reassigned and even redeclared.
let a = 'hey I am an a!';
let a = 'now I am z!';
> Uncaught SyntaxError: Identifier 'a' has already been declared
var b = 'hey I am b!';
var b = 'now I am z!';
console.log(b);
> 'now I am z!'
Now after this code snippet, if you could not manage the previous one, have a look again.
Summary
JavaScript scopes may be confusing. It may be daunting and hard. But hey, we all have passed through this. Try to practice with scopes. Play with variables in different parts of your script and functions. Try to nest 10 functions and before you run it, put everything on paper. How are you expecting console.log
statements print out. What will be the order? Make it harder. Add let
, const
and var
inside your functions and try to reassign and redeclare variables. Put on paper. Can you still trace them?
I bet once you do this exercises few times, you will see the picture. You will be able to folow the data flow from the arguments passed to the first function and down to the most inner function. Imagination is what I want you to engage.
Hope it was not confusing and helped you. Even a little. It was a great help to me too. Writing this post was hard and imaginary world is not perfect.
See you around!
Top comments (0)