WEBVTT

1
00:00:00.840 --> 00:00:03.090
<v Jonas>Let's continue our journey</v>

2
00:00:03.090 --> 00:00:07.330
of diving really deep into how JavaScript actually works

3
00:00:07.330 --> 00:00:08.960
behind the scenes.

4
00:00:08.960 --> 00:00:11.450
I really hope you have enjoyed it so far

5
00:00:11.450 --> 00:00:14.370
and are able to see the immense value

6
00:00:14.370 --> 00:00:17.460
that these lectures bring to the table.

7
00:00:17.460 --> 00:00:19.170
Now, after this lecture,

8
00:00:19.170 --> 00:00:22.560
there will finally be another coding lecture.

9
00:00:22.560 --> 00:00:25.223
So hang tight, we're almost there.

10
00:00:27.070 --> 00:00:30.770
But now let's get started with this lecture.

11
00:00:30.770 --> 00:00:33.430
So we learned in the last lecture

12
00:00:33.430 --> 00:00:37.810
that each execution context has a variable environment,

13
00:00:37.810 --> 00:00:41.340
a scope chain and a this keyword.

14
00:00:41.340 --> 00:00:44.510
So in this lecture, let's learn what scope

15
00:00:44.510 --> 00:00:46.200
and a scope chain are,

16
00:00:46.200 --> 00:00:49.970
why they are so important and how they work.

17
00:00:49.970 --> 00:00:51.930
And let's start by understanding

18
00:00:51.930 --> 00:00:54.190
what scoping actually means,

19
00:00:54.190 --> 00:00:57.930
and learn about some related concepts as well.

20
00:00:57.930 --> 00:01:02.250
So scoping controls how our program's variables

21
00:01:02.250 --> 00:01:06.293
are organized and accessed by the JavaScript engine.

22
00:01:07.140 --> 00:01:10.430
So basically scoping asks the question,

23
00:01:10.430 --> 00:01:12.560
where do variables live?

24
00:01:12.560 --> 00:01:16.993
Or where can we access a certain variable and where not?

25
00:01:18.030 --> 00:01:19.330
Now in JavaScript,

26
00:01:19.330 --> 00:01:22.720
we have something called lexical scoping.

27
00:01:22.720 --> 00:01:26.060
And lexical scoping means that the way variables

28
00:01:26.060 --> 00:01:28.330
are organized and accessed

29
00:01:28.330 --> 00:01:32.400
is entirely controlled by the placement of functions

30
00:01:32.400 --> 00:01:35.710
and of blocks in the programs code.

31
00:01:35.710 --> 00:01:39.470
For example, a function that is written inside

32
00:01:39.470 --> 00:01:42.940
another function has access to the variables

33
00:01:42.940 --> 00:01:45.930
of the parent function, okay?

34
00:01:45.930 --> 00:01:49.550
So again, variable scoping is influenced

35
00:01:49.550 --> 00:01:54.550
by where exactly we write our functions and code blocks.

36
00:01:55.120 --> 00:01:58.370
Okay, and now about scope itself.

37
00:01:58.370 --> 00:02:01.300
Scope is the space or environment

38
00:02:01.300 --> 00:02:04.430
in which a certain variable is declared,

39
00:02:04.430 --> 00:02:06.230
simple as that.

40
00:02:06.230 --> 00:02:08.050
And in the case of functions,

41
00:02:08.050 --> 00:02:10.870
that's essentially the variable environment

42
00:02:10.870 --> 00:02:15.020
which is stored in the functions execution context.

43
00:02:15.020 --> 00:02:17.210
So if now you're asking yourself,

44
00:02:17.210 --> 00:02:19.460
what's the difference between scope

45
00:02:19.460 --> 00:02:21.770
and variable environment?

46
00:02:21.770 --> 00:02:25.510
Then the answer is that for the case of functions,

47
00:02:25.510 --> 00:02:27.730
it's basically the same.

48
00:02:27.730 --> 00:02:30.770
Now in JavaScript, we have the global scope,

49
00:02:30.770 --> 00:02:33.690
function scope, and block scope.

50
00:02:33.690 --> 00:02:36.340
And we will talk about these in a second.

51
00:02:36.340 --> 00:02:39.560
But first, let's also define what the scope

52
00:02:39.560 --> 00:02:41.620
of a variable is.

53
00:02:41.620 --> 00:02:46.590
So the scope of a variable is basically the entire region

54
00:02:46.590 --> 00:02:51.170
of our code, where a certain variable can be accessed.

55
00:02:51.170 --> 00:02:55.170
Now, some people use the word scope for all of this,

56
00:02:55.170 --> 00:02:58.600
but I like to define all these concepts that we have here

57
00:02:58.600 --> 00:03:03.160
in a clear way, because actually subtle differences.

58
00:03:03.160 --> 00:03:06.070
For example, if you take a close look at it,

59
00:03:06.070 --> 00:03:09.940
scope is not the same as scope of a variable.

60
00:03:09.940 --> 00:03:14.430
And so you should know about the subtle differences, right?

61
00:03:14.430 --> 00:03:18.240
And I know it might still sound all the same for now,

62
00:03:18.240 --> 00:03:21.040
but after looking at a couple of examples

63
00:03:21.040 --> 00:03:23.050
and writing some real code,

64
00:03:23.050 --> 00:03:26.563
you will understand everything I just showed you here.

65
00:03:27.840 --> 00:03:31.000
Anyway, let's now talk about the three different types

66
00:03:31.000 --> 00:03:33.470
of scope in JavaScript.

67
00:03:33.470 --> 00:03:38.470
So that's global scope, function scope and block scope.

68
00:03:38.750 --> 00:03:42.030
And remember, scope is the place in our code

69
00:03:42.030 --> 00:03:44.940
where variables are declared.

70
00:03:44.940 --> 00:03:48.310
And when I say variables, the exact same thing

71
00:03:48.310 --> 00:03:50.800
is true for functions as well.

72
00:03:50.800 --> 00:03:54.420
Because in the end, functions are just values

73
00:03:54.420 --> 00:03:56.990
that are stored in variables.

74
00:03:56.990 --> 00:04:01.120
So first, the global scope is once more

75
00:04:01.120 --> 00:04:03.430
for top level code.

76
00:04:03.430 --> 00:04:06.270
So this is for variables that are declared

77
00:04:06.270 --> 00:04:09.930
outside of any function or block.

78
00:04:09.930 --> 00:04:12.840
These variables will be accessible everywhere

79
00:04:12.840 --> 00:04:17.050
in our program, in all functions and all blocks.

80
00:04:17.050 --> 00:04:19.830
So really, everywhere.

81
00:04:19.830 --> 00:04:23.730
Next, each and every function creates a scope.

82
00:04:23.730 --> 00:04:27.120
And the variables declared inside that function scope

83
00:04:27.120 --> 00:04:30.230
are only accessible inside that function.

84
00:04:30.230 --> 00:04:33.230
This is also called a local scope

85
00:04:33.230 --> 00:04:35.800
opposed to the global scope.

86
00:04:35.800 --> 00:04:40.150
So local variables live in the function so to say.

87
00:04:40.150 --> 00:04:41.920
And outside of the function,

88
00:04:41.920 --> 00:04:45.740
the variables are then not accessible at all.

89
00:04:45.740 --> 00:04:48.390
Again, this is technically the same

90
00:04:48.390 --> 00:04:51.130
as the functions variable environment,

91
00:04:51.130 --> 00:04:54.280
but we still need to give it the name of scope

92
00:04:54.280 --> 00:04:55.510
in this context,

93
00:04:55.510 --> 00:04:58.610
because blocks also creates scopes.

94
00:04:58.610 --> 00:05:01.010
Anyway, in this example here,

95
00:05:01.010 --> 00:05:06.010
the now variable is 2037 inside the cog H function.

96
00:05:06.560 --> 00:05:09.240
And therefore, we can use it in the function

97
00:05:09.240 --> 00:05:10.960
to do calculations.

98
00:05:10.960 --> 00:05:13.260
But outside of the function,

99
00:05:13.260 --> 00:05:15.730
as we try to log it to the console,

100
00:05:15.730 --> 00:05:18.440
we get a reference error.

101
00:05:18.440 --> 00:05:22.010
So JavaScript is trying to find the now variable

102
00:05:22.010 --> 00:05:23.770
in this global scope,

103
00:05:23.770 --> 00:05:27.370
so outside of the function, but it cannot find it.

104
00:05:27.370 --> 00:05:29.750
And so there is gonna be an error.

105
00:05:29.750 --> 00:05:32.430
And if you remember, or pick game project

106
00:05:32.430 --> 00:05:34.060
from the previous section,

107
00:05:34.060 --> 00:05:36.820
there is also the reason why we had to declare

108
00:05:36.820 --> 00:05:41.080
a couple of variables outside of the init function,

109
00:05:41.080 --> 00:05:42.410
remember that?

110
00:05:42.410 --> 00:05:45.920
So we had some variables declared in the init function,

111
00:05:45.920 --> 00:05:47.570
and then that gave us an error

112
00:05:47.570 --> 00:05:50.030
because other functions were trying

113
00:05:50.030 --> 00:05:51.860
to access these variables.

114
00:05:51.860 --> 00:05:54.580
But of course they were in the function scope.

115
00:05:54.580 --> 00:05:56.860
And so they were locally scoped,

116
00:05:56.860 --> 00:05:58.210
and so we couldn't access them

117
00:05:58.210 --> 00:06:02.400
outside of that function where they were declared.

118
00:06:02.400 --> 00:06:04.610
And here, it actually does not matter

119
00:06:04.610 --> 00:06:07.230
what kind of function we're using.

120
00:06:07.230 --> 00:06:10.380
So function declarations, function expressions

121
00:06:10.380 --> 00:06:14.223
and arrow functions all create their own scope.

122
00:06:15.260 --> 00:06:19.500
Now traditionally, only functions used to create scopes

123
00:06:19.500 --> 00:06:20.850
in JavaScript.

124
00:06:20.850 --> 00:06:25.850
But starting in ES6, blocks also creates scopes now.

125
00:06:25.860 --> 00:06:26.810
And with blocks,

126
00:06:26.810 --> 00:06:29.970
we mean everything that is between curly braces,

127
00:06:29.970 --> 00:06:34.510
such as the block of an if statement or a for loop.

128
00:06:34.510 --> 00:06:36.920
So just like with functions,

129
00:06:36.920 --> 00:06:39.570
variables declared inside a block

130
00:06:39.570 --> 00:06:42.350
are only accessible inside that block

131
00:06:42.350 --> 00:06:44.970
and not outside of it.

132
00:06:44.970 --> 00:06:47.950
Now, the big difference is that block scopes

133
00:06:47.950 --> 00:06:52.950
only apply to variables declared with let or const, okay?

134
00:06:53.540 --> 00:06:57.500
So again, only let and const variables

135
00:06:57.500 --> 00:07:01.600
are restricted to the block in which they were created.

136
00:07:01.600 --> 00:07:04.910
That's why we say that let and const variables

137
00:07:04.910 --> 00:07:06.710
are block scoped.

138
00:07:06.710 --> 00:07:10.890
So if I declared a variable using var in this block,

139
00:07:10.890 --> 00:07:14.520
then that variable would actually still be accessible

140
00:07:14.520 --> 00:07:16.550
outside of the block,

141
00:07:16.550 --> 00:07:19.430
and would be scoped to the current function

142
00:07:19.430 --> 00:07:21.410
or to the global scope.

143
00:07:21.410 --> 00:07:25.570
And so we say that var is function scoped.

144
00:07:25.570 --> 00:07:27.970
So in ES5 and before,

145
00:07:27.970 --> 00:07:31.260
we only had global scope and function scope.

146
00:07:31.260 --> 00:07:35.400
And that's why ES5 variables declared with var,

147
00:07:35.400 --> 00:07:39.080
only care about functions, but not about blocks.

148
00:07:39.080 --> 00:07:40.960
They simply ignore them.

149
00:07:40.960 --> 00:07:44.170
Finally, also starting in ES6,

150
00:07:44.170 --> 00:07:47.070
all functions are now also block scoped,

151
00:07:47.070 --> 00:07:49.010
at least in strict mode,

152
00:07:49.010 --> 00:07:52.040
which you should always be using anyway.

153
00:07:52.040 --> 00:07:55.420
And just like with let and const variables,

154
00:07:55.420 --> 00:07:58.750
this means that functions declared inside a block

155
00:07:58.750 --> 00:08:03.410
are only accessible inside that block, okay?

156
00:08:03.410 --> 00:08:06.730
And we will see examples of all that in the next video,

157
00:08:06.730 --> 00:08:09.023
when we're gonna go back to coding.

158
00:08:10.230 --> 00:08:13.930
So to recap, let and const variables

159
00:08:13.930 --> 00:08:17.260
as well as functions are block scoped.

160
00:08:17.260 --> 00:08:20.440
And if you already know other programming languages,

161
00:08:20.440 --> 00:08:23.090
block scoping is probably more in line

162
00:08:23.090 --> 00:08:25.230
with what you already know.

163
00:08:25.230 --> 00:08:28.680
Function scopes are weird for some beginners

164
00:08:28.680 --> 00:08:30.400
in the JavaScript world.

165
00:08:30.400 --> 00:08:35.070
And that's why block scopes were introduced in ES6.

166
00:08:35.070 --> 00:08:38.440
But now to understand all this a little bit better,

167
00:08:38.440 --> 00:08:42.560
let's actually look at a more real and detailed example

168
00:08:42.560 --> 00:08:45.493
and also learn about the scope chain.

169
00:08:47.520 --> 00:08:50.520
And here we have some code with different functions

170
00:08:50.520 --> 00:08:51.650
and blocks,

171
00:08:51.650 --> 00:08:53.720
and we're gonna take a look at the scopes

172
00:08:53.720 --> 00:08:58.330
that are in this code as well as build the scope chain.

173
00:08:58.330 --> 00:09:02.290
And of course, we start with the global scope.

174
00:09:02.290 --> 00:09:05.030
As you can see, the myName variable

175
00:09:05.030 --> 00:09:07.360
is the only variable declaration

176
00:09:07.360 --> 00:09:10.100
that we have in the global scope.

177
00:09:10.100 --> 00:09:12.600
Now, technically, the first function

178
00:09:12.600 --> 00:09:14.700
also counts as a variable

179
00:09:14.700 --> 00:09:17.010
that is present in the global scope,

180
00:09:17.010 --> 00:09:18.870
but I want to keep it simple here.

181
00:09:18.870 --> 00:09:22.180
And so I will only consider variable declarations

182
00:09:22.180 --> 00:09:24.510
and no functions, all right?

183
00:09:24.510 --> 00:09:27.500
Just keep in mind that whatever I'm explaining here

184
00:09:27.500 --> 00:09:31.363
for variables also works the same for functions.

185
00:09:32.310 --> 00:09:35.020
Anyway, inside the global scope,

186
00:09:35.020 --> 00:09:38.220
we have a scope for the first function

187
00:09:38.220 --> 00:09:42.820
because each function creates its own scope, remember?

188
00:09:42.820 --> 00:09:44.970
And what's in the scope?

189
00:09:44.970 --> 00:09:47.870
Well, it's to age variable that's declared

190
00:09:47.870 --> 00:09:50.500
right at the top of the function.

191
00:09:50.500 --> 00:09:52.960
Next inside the first scope,

192
00:09:52.960 --> 00:09:55.670
let's now consider the second function,

193
00:09:55.670 --> 00:09:58.270
which will also create its own scope

194
00:09:58.270 --> 00:10:01.820
containing the job variable set to teacher.

195
00:10:01.820 --> 00:10:03.060
So as you see,

196
00:10:03.060 --> 00:10:06.400
we have a nested structure of scopes

197
00:10:06.400 --> 00:10:09.490
with one scope inside the other.

198
00:10:09.490 --> 00:10:12.680
But now comes the actually interesting part.

199
00:10:12.680 --> 00:10:15.200
Because here in the second function,

200
00:10:15.200 --> 00:10:17.180
we have this line of code

201
00:10:17.180 --> 00:10:19.810
where we need the myName variable

202
00:10:19.810 --> 00:10:21.610
and the age variable,

203
00:10:21.610 --> 00:10:26.070
which were both not declared inside the current scope.

204
00:10:26.070 --> 00:10:28.720
But we really need these variables here,

205
00:10:28.720 --> 00:10:33.530
because otherwise we can't create this string here, right?

206
00:10:33.530 --> 00:10:35.700
So how can this be fixed?

207
00:10:35.700 --> 00:10:38.890
How will the JavaScript engine know the values

208
00:10:38.890 --> 00:10:40.970
of these variables?

209
00:10:40.970 --> 00:10:43.730
Well, the secret is that every scope

210
00:10:43.730 --> 00:10:46.520
always has access to all the variables

211
00:10:46.520 --> 00:10:49.050
from all its outer scopes.

212
00:10:49.050 --> 00:10:51.710
So from all its parent scopes.

213
00:10:51.710 --> 00:10:54.970
In our example, this means that the second scope

214
00:10:54.970 --> 00:10:57.950
can access the age variable from the scope

215
00:10:57.950 --> 00:10:59.900
of the first function.

216
00:10:59.900 --> 00:11:03.010
Of course, this also means that the first scope

217
00:11:03.010 --> 00:11:06.690
can access variables that are in the global scope,

218
00:11:06.690 --> 00:11:09.560
because that is the parent scope.

219
00:11:09.560 --> 00:11:11.480
As a consequence of this,

220
00:11:11.480 --> 00:11:14.870
the second scope will then also be able to access

221
00:11:14.870 --> 00:11:18.140
the myName variable from the global scope,

222
00:11:18.140 --> 00:11:21.030
because it has access to the variables

223
00:11:21.030 --> 00:11:22.713
from the first scope.

224
00:11:23.670 --> 00:11:28.180
And by the way, all this also applies to function arguments.

225
00:11:28.180 --> 00:11:31.043
But in this example, we just don't have any.

226
00:11:31.900 --> 00:11:36.590
And this is essentially how the scope chain works.

227
00:11:36.590 --> 00:11:37.650
In other words,

228
00:11:37.650 --> 00:11:41.130
if one scope needs to use a certain variable,

229
00:11:41.130 --> 00:11:43.940
but cannot find it in the current scope,

230
00:11:43.940 --> 00:11:46.460
it will look up in the scope chain

231
00:11:46.460 --> 00:11:48.840
and see if it can find a variable

232
00:11:48.840 --> 00:11:51.060
in one of the parent scopes.

233
00:11:51.060 --> 00:11:54.160
If it can, it will then use that variable.

234
00:11:54.160 --> 00:11:57.620
And if it can't, then there will be an error.

235
00:11:57.620 --> 00:12:00.503
And this process is called variable lookup.

236
00:12:01.870 --> 00:12:04.710
Now it's important to note that these variables

237
00:12:04.710 --> 00:12:09.460
are not copied from one scope to another, okay?

238
00:12:09.460 --> 00:12:13.190
Instead, scopes simply look up in the scope chain

239
00:12:13.190 --> 00:12:15.970
until they find a variable that they need

240
00:12:15.970 --> 00:12:17.940
and then they use it.

241
00:12:17.940 --> 00:12:20.760
What's also extremely important to note

242
00:12:20.760 --> 00:12:24.240
is that this does not work the other way around.

243
00:12:24.240 --> 00:12:27.560
A certain scope will never, ever have access

244
00:12:27.560 --> 00:12:29.940
to the variables of an inner scope.

245
00:12:29.940 --> 00:12:33.650
In this example, the first scope, for example,

246
00:12:33.650 --> 00:12:36.900
will never get access to the job variable

247
00:12:36.900 --> 00:12:40.840
that is stored in the second scope, okay?

248
00:12:40.840 --> 00:12:45.460
So again, one scope can only look up in a scope chain,

249
00:12:45.460 --> 00:12:48.520
but it cannot look down basically.

250
00:12:48.520 --> 00:12:50.840
So only parent scope can be used,

251
00:12:50.840 --> 00:12:52.603
but no child scopes.

252
00:12:53.450 --> 00:12:56.220
Anyway, with all this in place now,

253
00:12:56.220 --> 00:12:58.690
this line of code can be executed

254
00:12:58.690 --> 00:13:00.400
and print to the console.

255
00:13:00.400 --> 00:13:03.390
Jonas is a 30 year old teacher,

256
00:13:03.390 --> 00:13:06.460
even though the myName and age variables

257
00:13:06.460 --> 00:13:09.260
were not defined in the current scope.

258
00:13:09.260 --> 00:13:13.950
All the engine did was to get them from the scope chain.

259
00:13:13.950 --> 00:13:16.140
And as you might be noticing,

260
00:13:16.140 --> 00:13:20.180
we have actually already done this before in our own code.

261
00:13:20.180 --> 00:13:23.520
We just didn't really understand what was going on

262
00:13:23.520 --> 00:13:25.300
and how it all worked.

263
00:13:25.300 --> 00:13:27.940
But now we do know how it works.

264
00:13:27.940 --> 00:13:29.233
Amazing, right?

265
00:13:30.180 --> 00:13:33.870
Anyway, we still have one more scope left here,

266
00:13:33.870 --> 00:13:36.993
and that's the one created by this block here.

267
00:13:38.010 --> 00:13:40.880
Remember that starting with ES6,

268
00:13:40.880 --> 00:13:45.130
not only functions create scopes, but also blocks.

269
00:13:45.130 --> 00:13:49.810
However, these scopes only work for the ES6 variable types.

270
00:13:49.810 --> 00:13:52.930
So for let and const variables.

271
00:13:52.930 --> 00:13:56.010
That's why the only variable that's in the scope

272
00:13:56.010 --> 00:13:58.480
is the decade variable.

273
00:13:58.480 --> 00:14:02.650
The millennial variable isn't declared with const or let,

274
00:14:02.650 --> 00:14:07.380
and therefore it is not scoped to just this block.

275
00:14:07.380 --> 00:14:11.270
Instead, the millennial variable is actually part

276
00:14:11.270 --> 00:14:13.580
of the first function scope.

277
00:14:13.580 --> 00:14:17.780
So again, for a variable declared with var,

278
00:14:17.780 --> 00:14:20.490
block scopes don't apply at all.

279
00:14:20.490 --> 00:14:24.160
They are functions scoped, not block scoped.

280
00:14:24.160 --> 00:14:26.700
Let and const on the other hand

281
00:14:26.700 --> 00:14:30.440
are in fact blocks scoped, okay?

282
00:14:30.440 --> 00:14:32.690
This is one of the fundamental things

283
00:14:32.690 --> 00:14:36.710
that you need to keep in mind about let, const and var,

284
00:14:36.710 --> 00:14:39.760
and about scoping in general.

285
00:14:39.760 --> 00:14:43.280
So if you're taking notes and I hope you are taking

286
00:14:43.280 --> 00:14:44.970
lots of notes,

287
00:14:44.970 --> 00:14:47.543
then this must definitely be in there.

288
00:14:48.450 --> 00:14:50.330
Now about a scope chain,

289
00:14:50.330 --> 00:14:54.043
if the millennial variable is in the first function scope,

290
00:14:54.043 --> 00:14:57.010
then of course the second function scope

291
00:14:57.010 --> 00:14:59.130
also has access to it,

292
00:14:59.130 --> 00:15:02.550
even if it doesn't really need that variable.

293
00:15:02.550 --> 00:15:04.810
Also the scope chain does of course,

294
00:15:04.810 --> 00:15:07.500
apply to block scopes as well.

295
00:15:07.500 --> 00:15:10.400
And therefore in or if block scope,

296
00:15:10.400 --> 00:15:13.120
we get access to all the variables

297
00:15:13.120 --> 00:15:15.670
from all its outer scopes.

298
00:15:15.670 --> 00:15:17.950
So from the first function scope,

299
00:15:17.950 --> 00:15:20.890
and of course from the global scope.

300
00:15:20.890 --> 00:15:23.090
That's why I said in the last slide

301
00:15:23.090 --> 00:15:25.110
that variables in a global scope

302
00:15:25.110 --> 00:15:27.640
are accessible from everywhere.

303
00:15:27.640 --> 00:15:29.760
They are, because they are always

304
00:15:29.760 --> 00:15:32.290
at the top of the scope chain.

305
00:15:32.290 --> 00:15:35.350
In fact, we call variables in the global scope,

306
00:15:35.350 --> 00:15:39.200
global variables, very creative, right?

307
00:15:39.200 --> 00:15:43.670
But we actually use this term a lot in JavaScript.

308
00:15:43.670 --> 00:15:45.630
Now it's important to understand

309
00:15:45.630 --> 00:15:47.890
that our purple blocks scope

310
00:15:47.890 --> 00:15:50.920
does not get access to any variables

311
00:15:50.920 --> 00:15:53.890
from the yellow second function scope.

312
00:15:53.890 --> 00:15:56.240
And the same, the other way around.

313
00:15:56.240 --> 00:15:58.070
And why is that?

314
00:15:58.070 --> 00:16:00.920
Well it's because of lexical scoping

315
00:16:00.920 --> 00:16:03.230
as we learned in the last slide.

316
00:16:03.230 --> 00:16:05.710
So the way that we can access variables

317
00:16:05.710 --> 00:16:08.660
depends on where the scope is placed,

318
00:16:08.660 --> 00:16:11.650
so where it is written in the code.

319
00:16:11.650 --> 00:16:14.730
In this case, none of these two scopes is written

320
00:16:14.730 --> 00:16:17.110
inside of one another.

321
00:16:17.110 --> 00:16:20.810
They're both child scopes of the first function.

322
00:16:20.810 --> 00:16:24.400
We could even say that they are a sibling scopes.

323
00:16:24.400 --> 00:16:27.250
And so by the rules of lexical scoping,

324
00:16:27.250 --> 00:16:31.070
they cannot have access to each others variables,

325
00:16:31.070 --> 00:16:35.530
simply because one is not written inside the other one.

326
00:16:35.530 --> 00:16:37.540
We can also say that the scope chain

327
00:16:37.540 --> 00:16:40.803
only works upwards, not sideways.

328
00:16:41.860 --> 00:16:45.200
Okay, so this was a lot to take in,

329
00:16:45.200 --> 00:16:48.430
but I hope that everything's still keeps making sense

330
00:16:48.430 --> 00:16:49.670
at this point.

331
00:16:49.670 --> 00:16:51.400
And if not, don't worry,

332
00:16:51.400 --> 00:16:54.010
we will see all this working in practice

333
00:16:54.010 --> 00:16:56.060
in the next video.

334
00:16:56.060 --> 00:16:57.380
But for now, though,

335
00:16:57.380 --> 00:17:00.350
there is one more thing that we need to talk about,

336
00:17:00.350 --> 00:17:03.010
which is the difference between the scope chain

337
00:17:03.010 --> 00:17:04.740
and to call stack.

338
00:17:04.740 --> 00:17:08.360
I get a lot of questions about this all the time.

339
00:17:08.360 --> 00:17:10.840
And so I decided to talk about

340
00:17:10.840 --> 00:17:13.900
how the call stack, execution context,

341
00:17:13.900 --> 00:17:16.360
variable environments and scope

342
00:17:16.360 --> 00:17:19.310
are all related to one another.

343
00:17:19.310 --> 00:17:22.470
So before we move on to the next video.

344
00:17:22.470 --> 00:17:23.303
And once more,

345
00:17:23.303 --> 00:17:25.703
let's look at some more code here.

346
00:17:26.720 --> 00:17:31.550
So we have three functions called first, second and third,

347
00:17:31.550 --> 00:17:34.760
in order to make this easier to understand.

348
00:17:34.760 --> 00:17:37.430
We start by calling the first function,

349
00:17:37.430 --> 00:17:39.730
which then calls the second function,

350
00:17:39.730 --> 00:17:42.950
which in turn calls the third function.

351
00:17:42.950 --> 00:17:45.130
So from what we learned before,

352
00:17:45.130 --> 00:17:50.130
the call stack for this example will look like this, right?

353
00:17:50.780 --> 00:17:53.870
One execution context for each function

354
00:17:53.870 --> 00:17:57.250
in the exact order in which they were called.

355
00:17:57.250 --> 00:17:59.910
They also included the variable environment

356
00:17:59.910 --> 00:18:02.570
of each execution context.

357
00:18:02.570 --> 00:18:06.010
For now, all this has nothing to do with scopes

358
00:18:06.010 --> 00:18:08.490
or the scope chain, all right?

359
00:18:08.490 --> 00:18:12.000
All I'm doing is creating one execution context

360
00:18:12.000 --> 00:18:14.560
for each function call and filling it

361
00:18:14.560 --> 00:18:17.820
with the variables of that function.

362
00:18:17.820 --> 00:18:20.410
And you can pause the video here for a moment

363
00:18:20.410 --> 00:18:24.003
to understand the content of each variable environment.

364
00:18:25.440 --> 00:18:28.120
Okay, and now that you did that

365
00:18:28.120 --> 00:18:31.770
and we have all these variable environments in place,

366
00:18:31.770 --> 00:18:35.250
we can actually start building the scope chain.

367
00:18:35.250 --> 00:18:39.300
As always, we're gonna start with the global scope.

368
00:18:39.300 --> 00:18:42.390
And the variables available in the global scope

369
00:18:42.390 --> 00:18:46.360
are exactly the ones stored in the variable environment

370
00:18:46.360 --> 00:18:49.160
of the global execution context.

371
00:18:49.160 --> 00:18:52.020
And given everything we've learned so far,

372
00:18:52.020 --> 00:18:54.670
that makes sense, right?

373
00:18:54.670 --> 00:18:56.800
And note that in this example,

374
00:18:56.800 --> 00:19:00.640
I am actually including functions in each scope

375
00:19:00.640 --> 00:19:03.283
unlike we did in the previous slide.

376
00:19:04.150 --> 00:19:08.110
Now in the global scope, we also call the first function,

377
00:19:08.110 --> 00:19:11.880
which is the reason why we have an execution context for it

378
00:19:11.880 --> 00:19:13.530
in the call stack.

379
00:19:13.530 --> 00:19:17.260
And this function of course, also gets its own scope,

380
00:19:17.260 --> 00:19:20.140
which contains all the variables that are declared

381
00:19:20.140 --> 00:19:22.620
inside of the function.

382
00:19:22.620 --> 00:19:26.100
And once again, this is exactly the same

383
00:19:26.100 --> 00:19:27.900
as the variable environment

384
00:19:27.900 --> 00:19:30.820
of the functions execution context.

385
00:19:30.820 --> 00:19:32.930
However, that's not all

386
00:19:32.930 --> 00:19:36.550
because now we already know about the scope chain.

387
00:19:36.550 --> 00:19:40.740
So the first scope also gets access to all the variables

388
00:19:40.740 --> 00:19:42.440
from its parent scope,

389
00:19:42.440 --> 00:19:44.353
thanks to the scope chain.

390
00:19:45.220 --> 00:19:46.860
Now, as we already know,

391
00:19:46.860 --> 00:19:49.530
the scope chain is all about the order

392
00:19:49.530 --> 00:19:53.080
in which functions are written in the code.

393
00:19:53.080 --> 00:19:55.450
But what's really important to note here

394
00:19:55.450 --> 00:19:59.400
is that the scope chain has nothing to do with the order

395
00:19:59.400 --> 00:20:01.370
in which functions were called.

396
00:20:01.370 --> 00:20:05.180
Or in other words, the scope chain has nothing to do

397
00:20:05.180 --> 00:20:10.180
with the order of the execution contexts in the call stack.

398
00:20:10.280 --> 00:20:13.590
The scope chain does get the variable environments

399
00:20:13.590 --> 00:20:17.960
from the execution context as shown by the red arrows here,

400
00:20:17.960 --> 00:20:19.520
but that's it.

401
00:20:19.520 --> 00:20:22.870
The order of function calls is not relevant

402
00:20:22.870 --> 00:20:26.120
to the scope chain at all, all right?

403
00:20:26.120 --> 00:20:28.550
Really keep that in mind.

404
00:20:28.550 --> 00:20:32.000
Now, moving on to the second function now,

405
00:20:32.000 --> 00:20:37.000
once again, its scope is equal to its variable environment.

406
00:20:37.280 --> 00:20:41.650
Also it's lexically written within the first function.

407
00:20:41.650 --> 00:20:43.000
And so of course,

408
00:20:43.000 --> 00:20:47.120
it will have access to all its parent scopes as well.

409
00:20:47.120 --> 00:20:50.570
So we can say that the scope chain in a certain scope

410
00:20:50.570 --> 00:20:54.640
is equal to adding together all the variable environments

411
00:20:54.640 --> 00:20:57.000
of all the parent scopes.

412
00:20:57.000 --> 00:20:58.790
And so this is our scope,

413
00:20:58.790 --> 00:21:02.230
and the scope chain are built in the JavaScript engine

414
00:21:02.230 --> 00:21:03.663
behind the scenes.

415
00:21:04.650 --> 00:21:05.650
Okay.

416
00:21:05.650 --> 00:21:07.700
Now in the second function,

417
00:21:07.700 --> 00:21:11.220
we try to call the third function.

418
00:21:11.220 --> 00:21:13.270
But why does that work?

419
00:21:13.270 --> 00:21:16.150
Well, it works because the third function

420
00:21:16.150 --> 00:21:20.010
is in the scope chain of the second function scope

421
00:21:20.010 --> 00:21:23.770
as we can see here in our scope chain diagram.

422
00:21:23.770 --> 00:21:28.470
It's a function in the global scope or a global function,

423
00:21:28.470 --> 00:21:32.030
and therefore it's accessible everywhere.

424
00:21:32.030 --> 00:21:34.740
Of course, this will create a new scope

425
00:21:34.740 --> 00:21:38.363
along with the scope chain as we already know.

426
00:21:39.230 --> 00:21:43.330
Great, so what happens in this third function?

427
00:21:43.330 --> 00:21:47.120
Well, we're trying to act as variables B, C,

428
00:21:47.120 --> 00:21:49.750
D and A here.

429
00:21:49.750 --> 00:21:53.160
D is no problem because it's right there

430
00:21:53.160 --> 00:21:55.330
in the third function scope.

431
00:21:55.330 --> 00:21:57.610
So that one is easy.

432
00:21:57.610 --> 00:22:01.460
Then variable C is not in a local scope

433
00:22:01.460 --> 00:22:05.460
and so JavaScript needs to do a variable lookup.

434
00:22:05.460 --> 00:22:07.810
So it looks up in a scope chain

435
00:22:07.810 --> 00:22:10.120
looking for variable C,

436
00:22:10.120 --> 00:22:12.300
but it's not there.

437
00:22:12.300 --> 00:22:14.010
And of course it isn't,

438
00:22:14.010 --> 00:22:17.510
because C is defined in the second function,

439
00:22:17.510 --> 00:22:20.980
and there is just no way in which the third function

440
00:22:20.980 --> 00:22:25.420
can access variables defined in the second function.

441
00:22:25.420 --> 00:22:26.540
And that is true,

442
00:22:26.540 --> 00:22:30.640
even though it was the second function who called the third.

443
00:22:30.640 --> 00:22:32.780
And so here is even more proof

444
00:22:32.780 --> 00:22:35.400
that the order in which functions are called

445
00:22:35.400 --> 00:22:38.840
does not affect the scope chain at all.

446
00:22:38.840 --> 00:22:40.970
And so here as a result,

447
00:22:40.970 --> 00:22:42.990
we get the reference error

448
00:22:42.990 --> 00:22:46.700
because both C and B cannot be found

449
00:22:46.700 --> 00:22:50.063
in the third scope nor in the scope chain.

450
00:22:51.030 --> 00:22:51.863
Okay.

451
00:22:51.863 --> 00:22:54.810
And with this, I hope I made it crystal clear

452
00:22:54.810 --> 00:22:58.540
that execution context, variable environments,

453
00:22:58.540 --> 00:23:03.240
the call stack scope and the scope chain are all different,

454
00:23:03.240 --> 00:23:06.040
but still very related concepts.

455
00:23:06.040 --> 00:23:08.450
And if it's not yet crystal clear,

456
00:23:08.450 --> 00:23:12.220
then it's no problem to maybe rewatch this slide,

457
00:23:12.220 --> 00:23:15.423
or maybe even this entire lecture a little bit later.

458
00:23:16.540 --> 00:23:19.830
And I know that this was quite a long lecture

459
00:23:19.830 --> 00:23:23.000
with a ton of stuff to take in.

460
00:23:23.000 --> 00:23:25.250
And so here is a handy summary

461
00:23:25.250 --> 00:23:28.830
with the main takeaways from this video.

462
00:23:28.830 --> 00:23:32.667
So to start, scoping asks the question,

463
00:23:32.667 --> 00:23:34.990
"Where do variables live?"

464
00:23:34.990 --> 00:23:38.277
Or "Where can we access a certain variable,

465
00:23:38.277 --> 00:23:39.860
"and where not?"

466
00:23:39.860 --> 00:23:42.623
That's what scoping is all about.

467
00:23:43.480 --> 00:23:47.230
Now, there are three types scope in JavaScript.

468
00:23:47.230 --> 00:23:50.810
The global scope, scopes defined by functions

469
00:23:50.810 --> 00:23:55.570
and scopes defined by blocks, starting in ES6.

470
00:23:55.570 --> 00:24:00.200
However, only let and const variables are block scoped.

471
00:24:00.200 --> 00:24:04.030
Variables declared with var automatically end up

472
00:24:04.030 --> 00:24:05.993
in the closest function scope.

473
00:24:06.830 --> 00:24:10.590
Next in JavaScript, we have lexical scoping,

474
00:24:10.590 --> 00:24:14.580
which means that the rules of where we can access variables

475
00:24:14.580 --> 00:24:17.100
are based on where in the code functions

476
00:24:17.100 --> 00:24:18.943
and blocks are written.

477
00:24:19.820 --> 00:24:22.580
And now, let the magic begin,

478
00:24:22.580 --> 00:24:25.820
because every scope always has access

479
00:24:25.820 --> 00:24:29.710
to all the variables from all it's outer scopes.

480
00:24:29.710 --> 00:24:32.890
And this is what we call the scope chain.

481
00:24:32.890 --> 00:24:36.630
When a certain variable is not in the current scope,

482
00:24:36.630 --> 00:24:39.150
the engine looks up in the scope chain

483
00:24:39.150 --> 00:24:42.630
until it finds the variable that it's looking for,

484
00:24:42.630 --> 00:24:46.240
and this process is called variable lookup.

485
00:24:46.240 --> 00:24:48.720
It's important to note that the scope chain

486
00:24:48.720 --> 00:24:50.850
is a one way street.

487
00:24:50.850 --> 00:24:55.300
So a scope will never ever have access to the variables

488
00:24:55.300 --> 00:24:59.620
of an inner scope, only of outer scopes.

489
00:24:59.620 --> 00:25:03.490
We can also think of the scope chain in a certain scope

490
00:25:03.490 --> 00:25:05.690
as being equal to adding together

491
00:25:05.690 --> 00:25:10.280
all the variable environments of all the parent scopes.

492
00:25:10.280 --> 00:25:12.780
And finally, we need to keep in mind

493
00:25:12.780 --> 00:25:15.350
that the scope chain has nothing to do

494
00:25:15.350 --> 00:25:18.970
with the order in which functions were called.

495
00:25:18.970 --> 00:25:21.460
So the order of function calls

496
00:25:21.460 --> 00:25:24.343
does not affect the scope chain at all.

497
00:25:25.260 --> 00:25:27.920
Okay, and now that's actually it.

498
00:25:27.920 --> 00:25:32.410
This is in a nutshell, scoping in JavaScript.

499
00:25:32.410 --> 00:25:34.363
See you in the next video.

