All language subtitles for 092 Scope and The Scope Chain.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
hu Hungarian Download
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

Let's continue our journey

of diving really deep into how JavaScript actually works

behind the scenes.

I really hope you have enjoyed it so far

and are able to see the immense value

that these lectures bring to the table.

Now, after this lecture,

there will finally be another coding lecture.

So hang tight, we're almost there.

But now let's get started with this lecture.

So we learned in the last lecture

that each execution context has a variable environment,

a scope chain and a this keyword.

So in this lecture, let's learn what scope

and a scope chain are,

why they are so important and how they work.

And let's start by understanding

what scoping actually means,

and learn about some related concepts as well.

So scoping controls how our program's variables

are organized and accessed by the JavaScript engine.

So basically scoping asks the question,

where do variables live?

Or where can we access a certain variable and where not?

Now in JavaScript,

we have something called lexical scoping.

And lexical scoping means that the way variables

are organized and accessed

is entirely controlled by the placement of functions

and of blocks in the programs code.

For example, a function that is written inside

another function has access to the variables

of the parent function, okay?

So again, variable scoping is influenced

by where exactly we write our functions and code blocks.

Okay, and now about scope itself.

Scope is the space or environment

in which a certain variable is declared,

simple as that.

And in the case of functions,

that's essentially the variable environment

which is stored in the functions execution context.

So if now you're asking yourself,

what's the difference between scope

and variable environment?

Then the answer is that for the case of functions,

it's basically the same.

Now in JavaScript, we have the global scope,

function scope, and block scope.

And we will talk about these in a second.

But first, let's also define what the scope

of a variable is.

So the scope of a variable is basically the entire region

of our code, where a certain variable can be accessed.

Now, some people use the word scope for all of this,

but I like to define all these concepts that we have here

in a clear way, because actually subtle differences.

For example, if you take a close look at it,

scope is not the same as scope of a variable.

And so you should know about the subtle differences, right?

And I know it might still sound all the same for now,

but after looking at a couple of examples

and writing some real code,

you will understand everything I just showed you here.

Anyway, let's now talk about the three different types

of scope in JavaScript.

So that's global scope, function scope and block scope.

And remember, scope is the place in our code

where variables are declared.

And when I say variables, the exact same thing

is true for functions as well.

Because in the end, functions are just values

that are stored in variables.

So first, the global scope is once more

for top level code.

So this is for variables that are declared

outside of any function or block.

These variables will be accessible everywhere

in our program, in all functions and all blocks.

So really, everywhere.

Next, each and every function creates a scope.

And the variables declared inside that function scope

are only accessible inside that function.

This is also called a local scope

opposed to the global scope.

So local variables live in the function so to say.

And outside of the function,

the variables are then not accessible at all.

Again, this is technically the same

as the functions variable environment,

but we still need to give it the name of scope

in this context,

because blocks also creates scopes.

Anyway, in this example here,

the now variable is 2037 inside the cog H function.

And therefore, we can use it in the function

to do calculations.

But outside of the function,

as we try to log it to the console,

we get a reference error.

So JavaScript is trying to find the now variable

in this global scope,

so outside of the function, but it cannot find it.

And so there is gonna be an error.

And if you remember, or pick game project

from the previous section,

there is also the reason why we had to declare

a couple of variables outside of the init function,

remember that?

So we had some variables declared in the init function,

and then that gave us an error

because other functions were trying

to access these variables.

But of course they were in the function scope.

And so they were locally scoped,

and so we couldn't access them

outside of that function where they were declared.

And here, it actually does not matter

what kind of function we're using.

So function declarations, function expressions

and arrow functions all create their own scope.

Now traditionally, only functions used to create scopes

in JavaScript.

But starting in ES6, blocks also creates scopes now.

And with blocks,

we mean everything that is between curly braces,

such as the block of an if statement or a for loop.

So just like with functions,

variables declared inside a block

are only accessible inside that block

and not outside of it.

Now, the big difference is that block scopes

only apply to variables declared with let or const, okay?

So again, only let and const variables

are restricted to the block in which they were created.

That's why we say that let and const variables

are block scoped.

So if I declared a variable using var in this block,

then that variable would actually still be accessible

outside of the block,

and would be scoped to the current function

or to the global scope.

And so we say that var is function scoped.

So in ES5 and before,

we only had global scope and function scope.

And that's why ES5 variables declared with var,

only care about functions, but not about blocks.

They simply ignore them.

Finally, also starting in ES6,

all functions are now also block scoped,

at least in strict mode,

which you should always be using anyway.

And just like with let and const variables,

this means that functions declared inside a block

are only accessible inside that block, okay?

And we will see examples of all that in the next video,

when we're gonna go back to coding.

So to recap, let and const variables

as well as functions are block scoped.

And if you already know other programming languages,

block scoping is probably more in line

with what you already know.

Function scopes are weird for some beginners

in the JavaScript world.

And that's why block scopes were introduced in ES6.

But now to understand all this a little bit better,

let's actually look at a more real and detailed example

and also learn about the scope chain.

And here we have some code with different functions

and blocks,

and we're gonna take a look at the scopes

that are in this code as well as build the scope chain.

And of course, we start with the global scope.

As you can see, the myName variable

is the only variable declaration

that we have in the global scope.

Now, technically, the first function

also counts as a variable

that is present in the global scope,

but I want to keep it simple here.

And so I will only consider variable declarations

and no functions, all right?

Just keep in mind that whatever I'm explaining here

for variables also works the same for functions.

Anyway, inside the global scope,

we have a scope for the first function

because each function creates its own scope, remember?

And what's in the scope?

Well, it's to age variable that's declared

right at the top of the function.

Next inside the first scope,

let's now consider the second function,

which will also create its own scope

containing the job variable set to teacher.

So as you see,

we have a nested structure of scopes

with one scope inside the other.

But now comes the actually interesting part.

Because here in the second function,

we have this line of code

where we need the myName variable

and the age variable,

which were both not declared inside the current scope.

But we really need these variables here,

because otherwise we can't create this string here, right?

So how can this be fixed?

How will the JavaScript engine know the values

of these variables?

Well, the secret is that every scope

always has access to all the variables

from all its outer scopes.

So from all its parent scopes.

In our example, this means that the second scope

can access the age variable from the scope

of the first function.

Of course, this also means that the first scope

can access variables that are in the global scope,

because that is the parent scope.

As a consequence of this,

the second scope will then also be able to access

the myName variable from the global scope,

because it has access to the variables

from the first scope.

And by the way, all this also applies to function arguments.

But in this example, we just don't have any.

And this is essentially how the scope chain works.

In other words,

if one scope needs to use a certain variable,

but cannot find it in the current scope,

it will look up in the scope chain

and see if it can find a variable

in one of the parent scopes.

If it can, it will then use that variable.

And if it can't, then there will be an error.

And this process is called variable lookup.

Now it's important to note that these variables

are not copied from one scope to another, okay?

Instead, scopes simply look up in the scope chain

until they find a variable that they need

and then they use it.

What's also extremely important to note

is that this does not work the other way around.

A certain scope will never, ever have access

to the variables of an inner scope.

In this example, the first scope, for example,

will never get access to the job variable

that is stored in the second scope, okay?

So again, one scope can only look up in a scope chain,

but it cannot look down basically.

So only parent scope can be used,

but no child scopes.

Anyway, with all this in place now,

this line of code can be executed

and print to the console.

Jonas is a 30 year old teacher,

even though the myName and age variables

were not defined in the current scope.

All the engine did was to get them from the scope chain.

And as you might be noticing,

we have actually already done this before in our own code.

We just didn't really understand what was going on

and how it all worked.

But now we do know how it works.

Amazing, right?

Anyway, we still have one more scope left here,

and that's the one created by this block here.

Remember that starting with ES6,

not only functions create scopes, but also blocks.

However, these scopes only work for the ES6 variable types.

So for let and const variables.

That's why the only variable that's in the scope

is the decade variable.

The millennial variable isn't declared with const or let,

and therefore it is not scoped to just this block.

Instead, the millennial variable is actually part

of the first function scope.

So again, for a variable declared with var,

block scopes don't apply at all.

They are functions scoped, not block scoped.

Let and const on the other hand

are in fact blocks scoped, okay?

This is one of the fundamental things

that you need to keep in mind about let, const and var,

and about scoping in general.

So if you're taking notes and I hope you are taking

lots of notes,

then this must definitely be in there.

Now about a scope chain,

if the millennial variable is in the first function scope,

then of course the second function scope

also has access to it,

even if it doesn't really need that variable.

Also the scope chain does of course,

apply to block scopes as well.

And therefore in or if block scope,

we get access to all the variables

from all its outer scopes.

So from the first function scope,

and of course from the global scope.

That's why I said in the last slide

that variables in a global scope

are accessible from everywhere.

They are, because they are always

at the top of the scope chain.

In fact, we call variables in the global scope,

global variables, very creative, right?

But we actually use this term a lot in JavaScript.

Now it's important to understand

that our purple blocks scope

does not get access to any variables

from the yellow second function scope.

And the same, the other way around.

And why is that?

Well it's because of lexical scoping

as we learned in the last slide.

So the way that we can access variables

depends on where the scope is placed,

so where it is written in the code.

In this case, none of these two scopes is written

inside of one another.

They're both child scopes of the first function.

We could even say that they are a sibling scopes.

And so by the rules of lexical scoping,

they cannot have access to each others variables,

simply because one is not written inside the other one.

We can also say that the scope chain

only works upwards, not sideways.

Okay, so this was a lot to take in,

but I hope that everything's still keeps making sense

at this point.

And if not, don't worry,

we will see all this working in practice

in the next video.

But for now, though,

there is one more thing that we need to talk about,

which is the difference between the scope chain

and to call stack.

I get a lot of questions about this all the time.

And so I decided to talk about

how the call stack, execution context,

variable environments and scope

are all related to one another.

So before we move on to the next video.

And once more,

let's look at some more code here.

So we have three functions called first, second and third,

in order to make this easier to understand.

We start by calling the first function,

which then calls the second function,

which in turn calls the third function.

So from what we learned before,

the call stack for this example will look like this, right?

One execution context for each function

in the exact order in which they were called.

They also included the variable environment

of each execution context.

For now, all this has nothing to do with scopes

or the scope chain, all right?

All I'm doing is creating one execution context

for each function call and filling it

with the variables of that function.

And you can pause the video here for a moment

to understand the content of each variable environment.

Okay, and now that you did that

and we have all these variable environments in place,

we can actually start building the scope chain.

As always, we're gonna start with the global scope.

And the variables available in the global scope

are exactly the ones stored in the variable environment

of the global execution context.

And given everything we've learned so far,

that makes sense, right?

And note that in this example,

I am actually including functions in each scope

unlike we did in the previous slide.

Now in the global scope, we also call the first function,

which is the reason why we have an execution context for it

in the call stack.

And this function of course, also gets its own scope,

which contains all the variables that are declared

inside of the function.

And once again, this is exactly the same

as the variable environment

of the functions execution context.

However, that's not all

because now we already know about the scope chain.

So the first scope also gets access to all the variables

from its parent scope,

thanks to the scope chain.

Now, as we already know,

the scope chain is all about the order

in which functions are written in the code.

But what's really important to note here

is that the scope chain has nothing to do with the order

in which functions were called.

Or in other words, the scope chain has nothing to do

with the order of the execution contexts in the call stack.

The scope chain does get the variable environments

from the execution context as shown by the red arrows here,

but that's it.

The order of function calls is not relevant

to the scope chain at all, all right?

Really keep that in mind.

Now, moving on to the second function now,

once again, its scope is equal to its variable environment.

Also it's lexically written within the first function.

And so of course,

it will have access to all its parent scopes as well.

So we can say that the scope chain in a certain scope

is equal to adding together all the variable environments

of all the parent scopes.

And so this is our scope,

and the scope chain are built in the JavaScript engine

behind the scenes.

Okay.

Now in the second function,

we try to call the third function.

But why does that work?

Well, it works because the third function

is in the scope chain of the second function scope

as we can see here in our scope chain diagram.

It's a function in the global scope or a global function,

and therefore it's accessible everywhere.

Of course, this will create a new scope

along with the scope chain as we already know.

Great, so what happens in this third function?

Well, we're trying to act as variables B, C,

D and A here.

D is no problem because it's right there

in the third function scope.

So that one is easy.

Then variable C is not in a local scope

and so JavaScript needs to do a variable lookup.

So it looks up in a scope chain

looking for variable C,

but it's not there.

And of course it isn't,

because C is defined in the second function,

and there is just no way in which the third function

can access variables defined in the second function.

And that is true,

even though it was the second function who called the third.

And so here is even more proof

that the order in which functions are called

does not affect the scope chain at all.

And so here as a result,

we get the reference error

because both C and B cannot be found

in the third scope nor in the scope chain.

Okay.

And with this, I hope I made it crystal clear

that execution context, variable environments,

the call stack scope and the scope chain are all different,

but still very related concepts.

And if it's not yet crystal clear,

then it's no problem to maybe rewatch this slide,

or maybe even this entire lecture a little bit later.

And I know that this was quite a long lecture

with a ton of stuff to take in.

And so here is a handy summary

with the main takeaways from this video.

So to start, scoping asks the question,

"Where do variables live?"

Or "Where can we access a certain variable,

"and where not?"

That's what scoping is all about.

Now, there are three types scope in JavaScript.

The global scope, scopes defined by functions

and scopes defined by blocks, starting in ES6.

However, only let and const variables are block scoped.

Variables declared with var automatically end up

in the closest function scope.

Next in JavaScript, we have lexical scoping,

which means that the rules of where we can access variables

are based on where in the code functions

and blocks are written.

And now, let the magic begin,

because every scope always has access

to all the variables from all it's outer scopes.

And this is what we call the scope chain.

When a certain variable is not in the current scope,

the engine looks up in the scope chain

until it finds the variable that it's looking for,

and this process is called variable lookup.

It's important to note that the scope chain

is a one way street.

So a scope will never ever have access to the variables

of an inner scope, only of outer scopes.

We can also think of the scope chain in a certain scope

as being equal to adding together

all the variable environments of all the parent scopes.

And finally, we need to keep in mind

that the scope chain has nothing to do

with the order in which functions were called.

So the order of function calls

does not affect the scope chain at all.

Okay, and now that's actually it.

This is in a nutshell, scoping in JavaScript.

See you in the next video.

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