All language subtitles for 091 Execution Contexts and The Call Stack.en_US1

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranรฎ)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu

Original subtitles

In this lecture, let's answer the question.

How is JavaScript code executed?

We already know that it happens in a call stack

in the engine, but let's dig a bit deeper now.

And let's start

by supposing that our code was just finished compiling.

Just in the way that we learned in the last lecture.

So the code is now ready to be executed.

What happens then,

is that a so-called global execution context is created

for the top-level code.

And top-level code is basically code that is not

inside any function.

So again, in the beginning

only the code that is outside of functions will be executed.

And this makes sense, right?

Functions should only be executed when they are called.

And actually we saw this happening already

in our pig game project.

So there we had an init function,

which initialized our entire project

but in order to actually initialize the game

the first time that the page loaded,

we needed to call that function immediately

in our top-level code.

And so that's what I mean here.

But anyway, we can also see

what top-level code is in this example here.

So this name variable declaration

is clearly top-level code right?

And therefore it will be executed

in the global execution context.

Next, we have two functions, one expression,

and one declaration.

So these will also be declared,

so that they can be called later.

But the code inside the functions,

will only be executed when the functions are called.

Okay, so we know that a global execution context

is created for top-level code.

But now what exactly is an execution context?

Well, an execution context is an abstract concept.

But I define it basically as an environment

in which a piece of JavaScript is executed.

It's like a box that stores all the necessary information

for some code to be executed.

Such as local variables or arguments passed into a function.

So, JavaScript code always runs inside an execution context.

And to make this a bit more intuitive

let's imagine you order a pizza at a takeaway.

So usually that pizza comes in a box right?

And it might also come

with some other stuff that is necessary

for you to eat a pizza such as cutlery or a receipt,

so that you can actually pay for the pizza before eating it.

So, in this analogy,

the pizza is the JavaScript code to be executed,

and the box is of course the execution context

for our pizza.

And that's because eating the pizza happens inside the box

which is then the environment for eating pizza.

The box also contains cutlery and the receipt,

which are necessary to eat a pizza

or in other words, to execute the code, okay?

I hope that made sense,

and to made the concept of execution context

a little bit more clear.

Now, in any JavaScript project, no matter how large it is,

there is only ever one global execution context.

It's always there as the default context,

and it's where top-level code will execute.

And speaking of execute,

now that we have an environment

where the top-level code can be executed,

it finally is executed.

And there is not a lot to say about the execution itself.

It's just the computer CPU processing

the machine code that it received.

Okay, and once this first code,

so the top-level of code is finished,

functions finally start to execute as well.

And here is how that works.

For each and every function call,

and you execution context will be created

containing all the information that is necessary

to run exactly that function.

And the same goes for methods, of course,

because they're simply functions

attached to objects remember?

Anyway, all these execution contexts together,

make up the call stack that I mentioned before.

But more on that in a second.

Now, when all functions are done executing,

the engine will basically keep waiting

for callback functions to arrive

so that it can execute these.

For example, a callback function associated

with a click event.

And remember, that it's the event loop who provides

these new callback functions

as we learned in the last lecture.

All right.

So we know now what an execution context is,

but don't really know what it's made of.

So, what's inside of it?

And so let's find that out next.

And the first thing that's inside any execution context

is a so-called variable environment.

In this environment,

all our variables and function declarations are stored,

and there is also a special arguments object.

This object contains,

as the name says all the arguments that were passed

into the function that the current execution context

belongs to.

Because remember each function

gets its own execution context

as soon as the function is called.

So basically all the variables

that are somehow declared inside a function,

will end up in its variable environment.

However, a function can also access variables

outside of the function.

And we have already seen that in action

throughout this course,

especially in the projects of the previous section.

And this works because of something called the scope chain.

And we will learn all about scoping

and the scope chain later in the section.

But for now, what you need to know

is that the scope chain basically consists of

references to variables that are located

outside of the current function.

And to keep track of the scope chain,

it is stored in each execution context.

Finally, each context also gets a special variable

called the this keyword.

And once more, there is a special lecture

just about the this keyword later in the section.

Okay.

Now, the content of the execution context,

so variable environment, scope chain

and this keyword is generated in a so-called creation phase.

Which happens right before execution.

And now just one final

but very important detail that we need to keep in mind,

is that execution contexts belonging to arrow functions,

do not get their own arguments keyword,

nor do they get the this keyword, okay?

So, basically arrow functions

don't have the arguments object

and the this keyword.

Instead, they can use the arguments object,

and the this keyword

from their closest regular function parent.

And this is an extremely important detail to remember

about arrow functions and we will come back to it later.

So these are the things

that are necessary to run each function

as well as the code in the top-level.

Now behind the scenes, it's actually even more complex

but I think we're fine like this, aren't we?

And now let's actually try to simulate the creation phase

for this code example here.

So, as you hopefully know, by now,

we will get one global execution context

and one for each function.

So one for the first function,

and one for the second function.

In the global context,

we have the name variable declaration,

the first and second function declarations,

as well as the X variable declaration.

For the functions, the variable environment

will literally contain all the code

of a particular function.

Now the value of X is marked as unknown here,

because this value is the result

of the first function that we didn't run yet.

But we will simulate this in the next slide.

Now, technically none of these values actually become known

during the creation phase, but only in the execution phase.

So this is not 100% accurate here,

but it's just to illustrate

how these execution contexts work.

Okay? So just keep that in mind.

Anyway, now in the first function,

we have the a variable set to 1 and the b variable

which once again requires a function call

in order to become known.

Finally, the variable environment of the second function,

contains the C variable set to 2,

and since this is a irregular function,

so not an arrow function, it also has the arguments object.

And this object is an array,

which contains all the arguments that were passed

into the function when it was called.

In this case, as you can see, that's 7 and 9.

Quite simple right?

Well, it's simple because this is an extremely small

amount of code.

But now imagine there are hundreds of execution contexts

for hundreds of functions.

How will the engine keep track

of the order in which functions we're called?

And how will it know where it currently is

in the execution?

Well, that's where the call stack finally comes in.

And remember that the call stack,

together with the memory heap,

makes up the JavaScript engine itself.

But what actually is the call stack?

Well, it's basically a place where execution contexts

get stacked on top of each other,

in order to keep track

of where we are in the programs execution.

So the execution context that is on top of the stack,

is the one that is currently running.

And when it's finished running,

it will be removed from the stack,

and execution will go back

to the previous execution context.

And using the analogy from before,

it is as if you bought pizzas with some friends.

Each friend has a pizza box, and then you put the boxes

on top of each other, forming a stack,

in order to keep track, which pizza belongs to each friend.

Now, all this sounds a bit abstract, doesn't it?

And so to demonstrate how the call stack works,

let's walk through this code example together,

so that I can show you exactly what happens.

So, once the code is compiled,

top-level code will start execution.

And then as we learned in the beginning of the lecture,

a global execution context will be created

for the top-level of code, right?

So this is where all the code outside of any function

will be executed.

And what happens with this execution context?

That's right, it will be put in the call stack.

And since this context is now at the top of the stack,

it is the one where the code is currently being executed.

So, let's continue now with this execution.

So here, there is a simple variable declaration.

And then the first and the second functions are declared.

So nothing fancy, but that's just how normal top-level code

gets executed.

But then, in the last line

is where things start to get interesting.

Here, we declare the X variable,

with the value that is gonna be returned

from calling the first function.

And so let's actually call that function.

Now what happens immediately when a function is called?

Well, it gets its own execution context

so that it can run the code that's inside its body.

Perfect.

And what happens to the context?

Well, again it is put in the call stack,

on top of the current context,

and so it's now the new current execution context.

Great.

So, let's continue.

So we have yet another simple variable declaration here,

and this variable will of course be defined

in the variable environment

of the current execution context,

and not in the global context, right?

Then right in the next line, we have another function call.

So, let's call that function and move there.

And as you guessed a new execution context

was created right away for this second function.

And once more, it is pushed

onto the call stack and becomes the new act of context.

Now what's important to note here is that the execution

of the first function has now been paused, okay?

So again, we are running the second function now

and in the meantime, no other function is being executed.

The first function stopped at this point

where the second function was called

and will only continue as soon

as this second function returns.

And it has to work this way because remember,

JavaScript has only one thread of execution.

And so it can only do one thing at a time.

Okay? Never forget that.

Now, moving to the next line, we have a return statement

meaning that the function will finish its execution.

So, what does that mean for the call stack?

Well, it basically means

that the function's execution context,

will be popped off the stack

and disappear from the computer's memory.

At least that's what you need to know for now

because actually the popped off execution context

might keep living in memory.

But more about that later in the course.

Anyway, what happens next,

is that the previous execution context, will now be back

to being the active execution context again.

And so let's also go back to where we were

before in the code.

And I hope that by now,

you start to see how the call stack really keeps track

of the order of execution here.

Without the call stack,

how would the engine know which function

was being executed before?

It wouldn't know where to go back to, right?

And that's the beauty of the call stack.

It makes this process almost effortless.

So I like to use the analogy

of the call stack being like a map

for the JavaScript engine.

Because the call stack ensures

that the order of execution never gets lost.

Just like a map does, at least if you use it correctly.

All right.

So, we returned from the second function,

or back in the first function

where we have this calculation,

and then finally this first function also returns.

And so here the same as before happens.

So the current execution context gets popped off the stack,

and the previous context is now the current context

where code is executed.

In this case, we're back to the global execution context

and the line of code where the first function

was first called.

So here, the return value is finally assigned to X

and the execution is finished.

Now the program will now actually stay in this state

for forever until it is eventually really finished.

And that only happens like when we close the browser tab,

or the browser window.

Only when the program is really finished like this,

is when the global execution context

is also popped off the stack.

And this is in a nutshell how the call stack works.

So hopefully it makes sense now that we say

that Java script code runs inside the call stack.

And actually it is more accurate to say

that code runs inside of execution contexts

that are in the stack.

But the general point is that code runs in the call stack,

which is of course true.

Great.

Next up, we will learn some more

about the variable environment,

and how variables are created.

So stay tuned for the next video.

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.