WEBVTT

1
00:00:01.379 --> 00:00:03.930
<v Jonas>There is an almost mystical feature</v>

2
00:00:03.930 --> 00:00:07.410
of JavaScript functions that many developers

3
00:00:07.410 --> 00:00:09.900
fail to fully understand.

4
00:00:09.900 --> 00:00:14.070
And what I'm talking about is something called closures.

5
00:00:14.070 --> 00:00:17.100
So when I ask my students what's the hardest JavaScript

6
00:00:17.100 --> 00:00:20.490
concept to understand, then many people say

7
00:00:20.490 --> 00:00:22.290
that it's closures.

8
00:00:22.290 --> 00:00:25.410
However, I believe that with the right explanation,

9
00:00:25.410 --> 00:00:27.840
it's actually not that hard,

10
00:00:27.840 --> 00:00:30.660
especially when you already understood everything

11
00:00:30.660 --> 00:00:33.030
that you learned before in this course,

12
00:00:33.030 --> 00:00:36.330
such as execution context, the call stack

13
00:00:36.330 --> 00:00:37.800
and the scope chain.

14
00:00:37.800 --> 00:00:40.800
Because closures kind of bring all of these concepts

15
00:00:40.800 --> 00:00:45.360
together in a beautiful, almost magical way.

16
00:00:45.360 --> 00:00:49.473
So enough talk, let's see what closures are all about.

17
00:00:51.390 --> 00:00:54.960
So I'm gonna start by creating a new function here

18
00:00:54.960 --> 00:00:57.843
called secure booking.

19
00:01:00.450 --> 00:01:04.800
And it is this function that will create the closure.

20
00:01:04.800 --> 00:01:08.550
Now the first thing that I need to tell you about closures

21
00:01:08.550 --> 00:01:13.550
is that a closure is not a feature that we explicitly use.

22
00:01:13.710 --> 00:01:16.530
So we don't create closures manually,

23
00:01:16.530 --> 00:01:20.310
like we create a new array or a new function.

24
00:01:20.310 --> 00:01:23.130
So a closure simply happens automatically

25
00:01:23.130 --> 00:01:25.020
in certain situations.

26
00:01:25.020 --> 00:01:28.320
We just need to recognize those situations.

27
00:01:28.320 --> 00:01:31.590
And so that's what we're gonna do here in this example.

28
00:01:31.590 --> 00:01:34.350
So we will create one of those situations

29
00:01:34.350 --> 00:01:37.773
so that we can then take a look at a closure.

30
00:01:38.730 --> 00:01:41.410
So anyway, let's now continue writing this example

31
00:01:43.740 --> 00:01:46.530
and I'm calling this one passenger count

32
00:01:46.530 --> 00:01:48.810
and it'll start at zero,

33
00:01:48.810 --> 00:01:51.690
but we will be able to manipulate it.

34
00:01:51.690 --> 00:01:54.480
And I'm calling this function here secure booking

35
00:01:54.480 --> 00:01:58.890
because this passenger count variable cannot be manipulated

36
00:01:58.890 --> 00:02:01.083
and accessed from the outside.

37
00:02:02.670 --> 00:02:05.370
So, and now what's special about this function

38
00:02:05.370 --> 00:02:09.153
is that it will return a new function.

39
00:02:12.600 --> 00:02:14.790
And what we do in this function

40
00:02:14.790 --> 00:02:18.303
is to update the passenger count variable.

41
00:02:19.230 --> 00:02:22.803
So the variable that is defined in the parent function.

42
00:02:23.820 --> 00:02:25.680
So that's important.

43
00:02:25.680 --> 00:02:27.810
And then let's just log the new

44
00:02:27.810 --> 00:02:29.943
passenger count to the console.

45
00:02:32.790 --> 00:02:34.263
So passenger count.

46
00:02:36.630 --> 00:02:41.130
Alright, and now let's call the secure booking function

47
00:02:41.130 --> 00:02:44.343
and then store the result in a variable called booker.

48
00:02:46.770 --> 00:02:48.420
And so this is actually pretty similar

49
00:02:48.420 --> 00:02:51.840
to what we did previously in the lecture

50
00:02:51.840 --> 00:02:54.480
of functions returning other functions.

51
00:02:54.480 --> 00:02:57.150
So we have one function here that we call,

52
00:02:57.150 --> 00:03:00.960
and this function will return this new function.

53
00:03:00.960 --> 00:03:03.030
And so as we call secure booking,

54
00:03:03.030 --> 00:03:05.700
it will return exactly this function

55
00:03:05.700 --> 00:03:09.090
and it will then be stored inside this booker.

56
00:03:09.090 --> 00:03:12.693
And so this here is gonna be now a function as well, right?

57
00:03:13.650 --> 00:03:16.140
So let's analyze in detail what happens

58
00:03:16.140 --> 00:03:18.900
when this line of code here is executed

59
00:03:18.900 --> 00:03:21.633
using all the concepts that we already know about.

60
00:03:23.130 --> 00:03:26.730
So this is exactly the code that we just wrote.

61
00:03:26.730 --> 00:03:29.760
Now before we start running the secure booking function

62
00:03:29.760 --> 00:03:32.220
down here, our code is running

63
00:03:32.220 --> 00:03:34.710
in the global execution context.

64
00:03:34.710 --> 00:03:36.960
And in there we currently only have

65
00:03:36.960 --> 00:03:39.180
this secure booking function.

66
00:03:39.180 --> 00:03:40.830
And so we can also say

67
00:03:40.830 --> 00:03:44.970
that the global scope now contains secure booking.

68
00:03:44.970 --> 00:03:48.510
Then when secure booking is actually executed,

69
00:03:48.510 --> 00:03:51.510
a new execution context is put on top

70
00:03:51.510 --> 00:03:52.983
of the execution stack.

71
00:03:53.820 --> 00:03:56.580
Now remember, each execution context

72
00:03:56.580 --> 00:03:59.640
has a variable environment which contains

73
00:03:59.640 --> 00:04:01.890
all its local variables.

74
00:04:01.890 --> 00:04:05.220
In this case, it only contains the passenger count

75
00:04:05.220 --> 00:04:06.363
set to zero.

76
00:04:07.200 --> 00:04:08.610
This variable environment

77
00:04:08.610 --> 00:04:11.460
is also the scope of this function.

78
00:04:11.460 --> 00:04:14.820
And so the scope chain of this execution context

79
00:04:14.820 --> 00:04:16.650
looks like this.

80
00:04:16.650 --> 00:04:19.740
So passenger count is in the local scope,

81
00:04:19.740 --> 00:04:23.850
but of course this scope also gets access to all variables

82
00:04:23.850 --> 00:04:28.850
of the parent scopes, and in this case just a global scope.

83
00:04:28.950 --> 00:04:32.490
Anyway, in the next line of the secure booking function,

84
00:04:32.490 --> 00:04:34.710
a new function is returned

85
00:04:34.710 --> 00:04:37.950
and it'll be stored in the booker variable.

86
00:04:37.950 --> 00:04:42.810
So the global context now also contains the booker variable.

87
00:04:42.810 --> 00:04:45.480
Alright, now what else happens

88
00:04:45.480 --> 00:04:48.750
when the secure booking function returns?

89
00:04:48.750 --> 00:04:52.080
That's right, it's execution context pops off

90
00:04:52.080 --> 00:04:54.630
the stack and disappears.

91
00:04:54.630 --> 00:04:58.230
So the secure booking function has done its job

92
00:04:58.230 --> 00:05:01.260
and has now finished execution.

93
00:05:01.260 --> 00:05:03.570
Now, it's very important to note

94
00:05:03.570 --> 00:05:06.660
that it's only the execution context itself

95
00:05:06.660 --> 00:05:08.880
that is gone from the stack.

96
00:05:08.880 --> 00:05:12.180
The variable environment containing passenger count

97
00:05:12.180 --> 00:05:14.910
is still stored in memory.

98
00:05:14.910 --> 00:05:17.790
And in particular this variable environment

99
00:05:17.790 --> 00:05:21.450
has been transferred to the heap in this case,

100
00:05:21.450 --> 00:05:23.490
but more on that later.

101
00:05:23.490 --> 00:05:28.440
So again, the execution context is gone at this point,

102
00:05:28.440 --> 00:05:31.680
but the variable passenger count set to zero

103
00:05:31.680 --> 00:05:34.830
still lives on in the engine's memory.

104
00:05:34.830 --> 00:05:36.450
And this is very important

105
00:05:36.450 --> 00:05:40.110
to keep in mind moving forward, alright?

106
00:05:40.110 --> 00:05:43.380
But most of this is actually nothing new

107
00:05:43.380 --> 00:05:45.600
at this point, right?

108
00:05:45.600 --> 00:05:48.030
All we did was analyze the call stack

109
00:05:48.030 --> 00:05:52.650
and the scope chain as we call the secure booking function.

110
00:05:52.650 --> 00:05:55.830
And this is gonna be very important to later understand

111
00:05:55.830 --> 00:05:58.110
and see the closure.

112
00:05:58.110 --> 00:06:02.640
So as of yet we didn't see any closure yet.

113
00:06:02.640 --> 00:06:06.300
All we did was using the knowledge that we already have

114
00:06:06.300 --> 00:06:10.620
to understand how this booker function was created.

115
00:06:10.620 --> 00:06:12.990
But now let's go back to our code

116
00:06:12.990 --> 00:06:15.660
to actually use the booker function

117
00:06:15.660 --> 00:06:18.633
and finally see the closure in action.

118
00:06:20.070 --> 00:06:21.780
So now that we understand

119
00:06:21.780 --> 00:06:24.570
how the booker function was created,

120
00:06:24.570 --> 00:06:26.170
let's now actually call it here.

121
00:06:27.990 --> 00:06:30.750
So calling it a couple of times here,

122
00:06:30.750 --> 00:06:34.050
and as we can see it doesn't need any arguments.

123
00:06:34.050 --> 00:06:36.753
There's no list of parameters, right?

124
00:06:38.280 --> 00:06:40.293
So let's call it here three times.

125
00:06:42.420 --> 00:06:46.260
And now let's reload the page here.

126
00:06:46.260 --> 00:06:50.760
And indeed we get 1, 2, 3 passengers.

127
00:06:50.760 --> 00:06:54.210
And so what this means is that the booker function

128
00:06:54.210 --> 00:06:58.050
was in fact able to increment the passenger count

129
00:06:58.050 --> 00:07:01.950
to one, then to two and then to three.

130
00:07:01.950 --> 00:07:04.050
But now if we think about this

131
00:07:04.050 --> 00:07:06.450
then how is this even possible?

132
00:07:06.450 --> 00:07:08.610
How can the booker function update

133
00:07:08.610 --> 00:07:10.470
this passenger count variable

134
00:07:10.470 --> 00:07:13.320
that's defined in a secure booking function

135
00:07:13.320 --> 00:07:17.130
that actually has already finished executing?

136
00:07:17.130 --> 00:07:18.810
And so as I just said,

137
00:07:18.810 --> 00:07:22.110
this function has already finished its execution,

138
00:07:22.110 --> 00:07:23.220
it is gone.

139
00:07:23.220 --> 00:07:27.120
So its execution context is no longer on the stack

140
00:07:27.120 --> 00:07:29.430
as we just saw in the slide.

141
00:07:29.430 --> 00:07:32.160
But still this inner function here,

142
00:07:32.160 --> 00:07:34.320
which is the booker function,

143
00:07:34.320 --> 00:07:38.400
is still able to access the passenger count variable

144
00:07:38.400 --> 00:07:40.830
that's inside of the booker function

145
00:07:40.830 --> 00:07:43.530
that should no longer exist.

146
00:07:43.530 --> 00:07:47.190
And maybe you can guess that what makes this possible

147
00:07:47.190 --> 00:07:48.870
is a closure.

148
00:07:48.870 --> 00:07:52.530
But before I explain exactly how the closure works,

149
00:07:52.530 --> 00:07:54.900
I want you to appreciate once more

150
00:07:54.900 --> 00:07:57.990
how strange this actually is.

151
00:07:57.990 --> 00:08:02.370
So again, this booker function here is simply a function

152
00:08:02.370 --> 00:08:05.700
that exists out here in the global environment

153
00:08:05.700 --> 00:08:08.340
or in the global scope, right?

154
00:08:08.340 --> 00:08:11.940
And the environment in which the function was created.

155
00:08:11.940 --> 00:08:15.420
So this here basically, this environment

156
00:08:15.420 --> 00:08:19.200
is no longer active, it is in fact gone,

157
00:08:19.200 --> 00:08:22.260
but still the booker function somehow continues

158
00:08:22.260 --> 00:08:24.090
to have access to the variables

159
00:08:24.090 --> 00:08:28.440
that were present at the time that the function was created.

160
00:08:28.440 --> 00:08:32.430
And in particular this passenger count variable here.

161
00:08:32.430 --> 00:08:35.820
And so that's exactly what the closure does.

162
00:08:35.820 --> 00:08:38.640
So we can say that a closure makes a function.

163
00:08:38.640 --> 00:08:41.910
Remember all the variables that existed

164
00:08:41.910 --> 00:08:45.630
at the function's birthplace essentially, right?

165
00:08:45.630 --> 00:08:49.620
So we can imagine the secure booking as being

166
00:08:49.620 --> 00:08:52.620
the birthplace of this function,

167
00:08:52.620 --> 00:08:55.200
so of the booker function essentially.

168
00:08:55.200 --> 00:08:59.310
And so this function remembers everything at its birthplace

169
00:08:59.310 --> 00:09:01.650
by the time it was created.

170
00:09:01.650 --> 00:09:04.140
And this cannot simply be explained

171
00:09:04.140 --> 00:09:06.300
with the scope chain alone.

172
00:09:06.300 --> 00:09:09.240
So we need to also understand the closure.

173
00:09:09.240 --> 00:09:13.650
And so let me know really explain how it actually works.

174
00:09:13.650 --> 00:09:17.430
So this is how we left the call stack and scope chain

175
00:09:17.430 --> 00:09:19.290
after the last slide.

176
00:09:19.290 --> 00:09:21.540
And let's now start by remembering

177
00:09:21.540 --> 00:09:24.840
that the execution context of secure booking

178
00:09:24.840 --> 00:09:27.000
was popped off the call stack

179
00:09:27.000 --> 00:09:29.820
after that function finished running together

180
00:09:29.820 --> 00:09:32.490
with its variable environment.

181
00:09:32.490 --> 00:09:34.800
Now also remember how we said

182
00:09:34.800 --> 00:09:37.560
that this environment which contains

183
00:09:37.560 --> 00:09:42.150
the passenger count variable is still stored in memory.

184
00:09:42.150 --> 00:09:43.950
But why is that?

185
00:09:43.950 --> 00:09:46.710
Didn't we learn earlier in the lecture about

186
00:09:46.710 --> 00:09:50.370
garbage collection that variables stored in the stack

187
00:09:50.370 --> 00:09:53.730
are destroyed as soon as the execution context

188
00:09:53.730 --> 00:09:55.950
pops off the stack?

189
00:09:55.950 --> 00:10:00.720
Well, yes we did, because that's usually the case.

190
00:10:00.720 --> 00:10:04.470
There is however, one exception that we talked about

191
00:10:04.470 --> 00:10:09.330
and that exception is the existence of a closure.

192
00:10:09.330 --> 00:10:13.770
So remember how we said that if an object is reachable

193
00:10:13.770 --> 00:10:17.580
by a closure, it cannot be garbage collected

194
00:10:17.580 --> 00:10:21.270
and will therefore stay in the heap indefinitely.

195
00:10:21.270 --> 00:10:24.900
And this actually applies to objects in the heap

196
00:10:24.900 --> 00:10:28.050
and to variable environments for variables

197
00:10:28.050 --> 00:10:32.130
that are stored in the stack as long as they're reachable

198
00:10:32.130 --> 00:10:34.050
by a closure.

199
00:10:34.050 --> 00:10:38.670
So in summary, the passenger count variable still exists

200
00:10:38.670 --> 00:10:42.930
because it is in fact reachable by a closure.

201
00:10:42.930 --> 00:10:47.280
That's the only reason, otherwise it would really be gone.

202
00:10:47.280 --> 00:10:51.090
But in this case, the engine moved the variable environment

203
00:10:51.090 --> 00:10:54.150
to the heap where it can stay forever.

204
00:10:54.150 --> 00:10:57.390
Again, because it's reachable by a closure

205
00:10:57.390 --> 00:11:00.900
and can therefore not be garbage collected.

206
00:11:00.900 --> 00:11:05.610
So this is why the passenger count variable still lives on.

207
00:11:05.610 --> 00:11:09.060
So the way memory and garbage collection work

208
00:11:09.060 --> 00:11:11.070
play an essential part here.

209
00:11:11.070 --> 00:11:12.150
Alright?

210
00:11:12.150 --> 00:11:15.240
And well, I told you that in this lecture

211
00:11:15.240 --> 00:11:17.160
everything would come together

212
00:11:17.160 --> 00:11:20.040
and so make sure that you understand all the stuff

213
00:11:20.040 --> 00:11:21.330
that we learned earlier.

214
00:11:21.330 --> 00:11:24.960
And so in this case that we learned about memory management

215
00:11:24.960 --> 00:11:26.940
and garbage collection.

216
00:11:26.940 --> 00:11:31.650
But anyway, now it's time to finally run the booker function

217
00:11:31.650 --> 00:11:35.100
and see what's exactly gonna happen here.

218
00:11:35.100 --> 00:11:38.670
And by the way, note that booker is really

219
00:11:38.670 --> 00:11:40.170
this function here.

220
00:11:40.170 --> 00:11:44.160
So located in the global scope, okay?

221
00:11:44.160 --> 00:11:46.410
So the first thing that's gonna happen

222
00:11:46.410 --> 00:11:48.270
when we run this function

223
00:11:48.270 --> 00:11:52.350
is that a new execution context is put on the top

224
00:11:52.350 --> 00:11:53.790
of the call stack

225
00:11:53.790 --> 00:11:57.570
and the variable environment of this context is empty

226
00:11:57.570 --> 00:12:00.390
simply because there are no variables declared

227
00:12:00.390 --> 00:12:01.533
in this function.

228
00:12:02.490 --> 00:12:05.490
Now what about the scope chain?

229
00:12:05.490 --> 00:12:08.790
Well, since booker is in the global context,

230
00:12:08.790 --> 00:12:12.300
it's simply a child scope of the global scope

231
00:12:12.300 --> 00:12:13.890
just like this.

232
00:12:13.890 --> 00:12:17.640
But maybe now by looking at this scope chain,

233
00:12:17.640 --> 00:12:20.550
you're starting to see a problem here.

234
00:12:20.550 --> 00:12:23.100
How will the booker function access

235
00:12:23.100 --> 00:12:25.260
the passenger count variable?

236
00:12:25.260 --> 00:12:28.020
It's nowhere to be found in the scope chain

237
00:12:28.020 --> 00:12:30.900
of this function, right?

238
00:12:30.900 --> 00:12:34.110
So this is where we now start to unveil

239
00:12:34.110 --> 00:12:36.690
the magic of the closure.

240
00:12:36.690 --> 00:12:39.570
I mean, we already know that the closure exists

241
00:12:39.570 --> 00:12:41.610
because we saw it in our code,

242
00:12:41.610 --> 00:12:44.130
but we don't really know what it is

243
00:12:44.130 --> 00:12:47.850
and why it exists in the first place.

244
00:12:47.850 --> 00:12:51.270
So the magic is basically this.

245
00:12:51.270 --> 00:12:55.590
Any function always has access to the variable environment

246
00:12:55.590 --> 00:13:00.270
of the execution context in which the function was created.

247
00:13:00.270 --> 00:13:04.350
In the case of booker, this function was created,

248
00:13:04.350 --> 00:13:09.350
so it was born in the execution context of secure booking,

249
00:13:09.390 --> 00:13:13.440
which we popped off the stack previously, right?

250
00:13:13.440 --> 00:13:17.340
So therefore the booker function will get access

251
00:13:17.340 --> 00:13:20.820
to this variable environment which contains

252
00:13:20.820 --> 00:13:23.160
the passenger count variable.

253
00:13:23.160 --> 00:13:26.280
So that's the magic trick right there.

254
00:13:26.280 --> 00:13:30.000
This is how the booker function will be able to read

255
00:13:30.000 --> 00:13:33.510
and to manipulate the passenger count variable.

256
00:13:33.510 --> 00:13:38.220
And so this connection is what we call the closure.

257
00:13:38.220 --> 00:13:42.240
So let's say all that again to make this really clear.

258
00:13:42.240 --> 00:13:46.560
So a function always has access to the variable environment

259
00:13:46.560 --> 00:13:50.520
of the execution context in which it was created

260
00:13:50.520 --> 00:13:54.450
even after that execution context is gone.

261
00:13:54.450 --> 00:13:57.330
And this last part is really important.

262
00:13:57.330 --> 00:14:00.930
The closure is then basically this variable environment

263
00:14:00.930 --> 00:14:05.100
attached to the function exactly as it was at the time

264
00:14:05.100 --> 00:14:08.640
and place that the function was created.

265
00:14:08.640 --> 00:14:11.550
And this probably still sounds confusing,

266
00:14:11.550 --> 00:14:15.120
but don't worry, I have some more familiar analogies

267
00:14:15.120 --> 00:14:16.950
in the next slide.

268
00:14:16.950 --> 00:14:20.220
For now, we are just trying to understand the mechanism

269
00:14:20.220 --> 00:14:21.600
behind the closure.

270
00:14:21.600 --> 00:14:24.540
So how it all works behind the scenes.

271
00:14:24.540 --> 00:14:26.700
So what matters the most here

272
00:14:26.700 --> 00:14:29.430
is that the booker function has access

273
00:14:29.430 --> 00:14:31.350
to the passenger count variable

274
00:14:31.350 --> 00:14:34.440
because it's basically defined in the scope

275
00:14:34.440 --> 00:14:38.070
in which the booker function was actually created.

276
00:14:38.070 --> 00:14:42.240
So in a sense, the scope chain is actually preserved

277
00:14:42.240 --> 00:14:44.730
through the closure even when a scope

278
00:14:44.730 --> 00:14:46.800
has already been destroyed

279
00:14:46.800 --> 00:14:50.340
because its execution context is gone.

280
00:14:50.340 --> 00:14:53.610
This means that even though the execution context

281
00:14:53.610 --> 00:14:55.680
has actually been destroyed,

282
00:14:55.680 --> 00:14:58.530
the variable environment somehow keeps living

283
00:14:58.530 --> 00:15:00.750
somewhere in the engine.

284
00:15:00.750 --> 00:15:03.270
Now we can say that the booker function

285
00:15:03.270 --> 00:15:05.940
closed-over its parent scope

286
00:15:05.940 --> 00:15:09.300
or over its parent variable environment.

287
00:15:09.300 --> 00:15:11.610
And this includes all function arguments,

288
00:15:11.610 --> 00:15:15.180
even though in this example we don't have any.

289
00:15:15.180 --> 00:15:19.740
And now this attached or closed-over variable environment

290
00:15:19.740 --> 00:15:22.440
stays with the function forever.

291
00:15:22.440 --> 00:15:26.880
It'll carry it around and be able to use it forever.

292
00:15:26.880 --> 00:15:29.280
To make it a bit more digestible

293
00:15:29.280 --> 00:15:32.310
we can also say that thanks to the closure,

294
00:15:32.310 --> 00:15:35.850
a function does not lose connection to variables

295
00:15:35.850 --> 00:15:38.640
that existed at the function's birthplace.

296
00:15:38.640 --> 00:15:41.610
That's a bit more intuitive, right?

297
00:15:41.610 --> 00:15:44.040
But anyway, let's see what happens now

298
00:15:44.040 --> 00:15:47.430
with execution of the booker function.

299
00:15:47.430 --> 00:15:50.010
So the function attempts to increase

300
00:15:50.010 --> 00:15:52.350
the passenger count variable,

301
00:15:52.350 --> 00:15:56.520
however, this variable is not in the current scope.

302
00:15:56.520 --> 00:16:00.450
And so JavaScript will immediately look into the closure

303
00:16:00.450 --> 00:16:03.390
and see if it can find the variable there.

304
00:16:03.390 --> 00:16:05.340
And so after running this function,

305
00:16:05.340 --> 00:16:09.330
the passenger count becomes 1, this message is logged

306
00:16:09.330 --> 00:16:13.740
and then the execution context is popped off the stack.

307
00:16:13.740 --> 00:16:16.380
Then execution moves to the next line,

308
00:16:16.380 --> 00:16:18.510
we get a new execution context

309
00:16:18.510 --> 00:16:20.400
and the closure is still there,

310
00:16:20.400 --> 00:16:25.170
still attached to the function and the value is still 1.

311
00:16:25.170 --> 00:16:28.260
And so now this function executes increasing

312
00:16:28.260 --> 00:16:32.463
the passenger count to two and logging a message again.

313
00:16:34.110 --> 00:16:36.090
And that's what closures are

314
00:16:36.090 --> 00:16:38.700
and how they work behind the scenes.

315
00:16:38.700 --> 00:16:42.120
And I know that this is all quite complex.

316
00:16:42.120 --> 00:16:42.960
So let me give you

317
00:16:42.960 --> 00:16:46.350
a couple different definitions of closure now.

318
00:16:46.350 --> 00:16:49.950
Some more formal ones and some more intuitive

319
00:16:49.950 --> 00:16:52.470
and maybe easier to grasp.

320
00:16:52.470 --> 00:16:55.140
And the most formal definition of closure

321
00:16:55.140 --> 00:16:57.090
is the one we already saw,

322
00:16:57.090 --> 00:17:00.270
which is that a closure is the closed-over

323
00:17:00.270 --> 00:17:03.450
variable environment of the execution context

324
00:17:03.450 --> 00:17:06.150
in which a function was created

325
00:17:06.150 --> 00:17:10.110
even after that execution context is gone.

326
00:17:10.110 --> 00:17:12.990
Or in other words, even after the function

327
00:17:12.990 --> 00:17:16.983
to which the execution context belongs has returned.

328
00:17:17.910 --> 00:17:20.970
Next and a bit easier to understand,

329
00:17:20.970 --> 00:17:24.780
a closure gives the function access to all the variables

330
00:17:24.780 --> 00:17:26.730
of its parent function.

331
00:17:26.730 --> 00:17:30.240
So the function in which it is defined

332
00:17:30.240 --> 00:17:34.290
even after that parent function has returned.

333
00:17:34.290 --> 00:17:38.010
So the function keeps a reference to its outer scope

334
00:17:38.010 --> 00:17:40.920
even after that outer scope is gone,

335
00:17:40.920 --> 00:17:44.583
which basically preserves the scope chain throughout time.

336
00:17:45.600 --> 00:17:47.640
Alright, another definition,

337
00:17:47.640 --> 00:17:51.900
or let's say analogy is that a closure makes sure

338
00:17:51.900 --> 00:17:55.590
that a function does never lose connection to the variables

339
00:17:55.590 --> 00:17:58.710
that existed at the function's birthplace.

340
00:17:58.710 --> 00:18:00.480
It remembers the variables

341
00:18:00.480 --> 00:18:03.600
even after the birthplace is gone.

342
00:18:03.600 --> 00:18:06.300
It's like a person who doesn't lose connection

343
00:18:06.300 --> 00:18:08.430
to their hometown.

344
00:18:08.430 --> 00:18:09.870
In this analogy,

345
00:18:09.870 --> 00:18:13.020
the person is the function and the hometown

346
00:18:13.020 --> 00:18:15.420
is the function's parent scope.

347
00:18:15.420 --> 00:18:17.910
And the function then doesn't lose the connection

348
00:18:17.910 --> 00:18:21.780
to the variables stored in this parent scope.

349
00:18:21.780 --> 00:18:24.393
And I hope that makes sense.

350
00:18:25.260 --> 00:18:27.690
Finally, some people like to think

351
00:18:27.690 --> 00:18:31.920
of this attached variable environment as a backpack.

352
00:18:31.920 --> 00:18:35.520
So in this analogy, a function has a backpack,

353
00:18:35.520 --> 00:18:38.880
which it carries around wherever it goes.

354
00:18:38.880 --> 00:18:41.640
And this backpack contains all the variables

355
00:18:41.640 --> 00:18:44.070
that were present in the environment

356
00:18:44.070 --> 00:18:46.710
in which the function was created.

357
00:18:46.710 --> 00:18:49.410
Then whenever a variable can't be found

358
00:18:49.410 --> 00:18:51.120
in the function scope,

359
00:18:51.120 --> 00:18:53.820
JavaScript will look into the backpack

360
00:18:53.820 --> 00:18:56.850
and take the missing variable from there.

361
00:18:56.850 --> 00:19:00.240
So kind of similar to the other definitions,

362
00:19:00.240 --> 00:19:03.510
but maybe a little bit more visual.

363
00:19:03.510 --> 00:19:07.440
So these are some different ways of defining closure,

364
00:19:07.440 --> 00:19:09.750
but they all mean the same thing.

365
00:19:09.750 --> 00:19:12.393
So they all represent the same idea.

366
00:19:13.290 --> 00:19:16.410
Finally, we need to understand that we do not

367
00:19:16.410 --> 00:19:18.930
have to create closures manually.

368
00:19:18.930 --> 00:19:21.630
And this is also what I already touched on

369
00:19:21.630 --> 00:19:24.090
at the beginning of the lecture.

370
00:19:24.090 --> 00:19:27.270
So instead, this is something that JavaScript

371
00:19:27.270 --> 00:19:29.610
does completely automatically.

372
00:19:29.610 --> 00:19:31.920
We don't have to do anything.

373
00:19:31.920 --> 00:19:34.080
Also, there is no way for us

374
00:19:34.080 --> 00:19:37.890
to explicitly access closed-over variables.

375
00:19:37.890 --> 00:19:41.700
That's because closures are not like a tangible thing.

376
00:19:41.700 --> 00:19:45.540
They're not like an object or so that we can access.

377
00:19:45.540 --> 00:19:48.270
So we cannot just reach into a closure

378
00:19:48.270 --> 00:19:50.430
and take variables from it.

379
00:19:50.430 --> 00:19:53.040
That's impossible because a closure

380
00:19:53.040 --> 00:19:56.910
is just an internal property of a function.

381
00:19:56.910 --> 00:19:59.790
We can observe that a closure happens

382
00:19:59.790 --> 00:20:02.790
because functions magically keep having access

383
00:20:02.790 --> 00:20:06.150
to variables that should no longer exist.

384
00:20:06.150 --> 00:20:10.260
But we cannot directly access these variables.

385
00:20:10.260 --> 00:20:13.980
However, what we can do is to actually take a look

386
00:20:13.980 --> 00:20:15.840
at this internal property.

387
00:20:15.840 --> 00:20:20.370
So at this backpack, so to say, in the console.

388
00:20:20.370 --> 00:20:23.583
So let's quickly do that before we finish this lecture.

389
00:20:25.320 --> 00:20:28.720
And we can do this by using console.dir

390
00:20:31.680 --> 00:20:33.813
and then of the booker function itself.

391
00:20:34.680 --> 00:20:39.480
So similar to console.log, but this one is a bit different.

392
00:20:39.480 --> 00:20:42.760
And so here we now get this function itself

393
00:20:44.400 --> 00:20:46.470
so we can get the arguments,

394
00:20:46.470 --> 00:20:50.550
the name property that we already took a look at before.

395
00:20:50.550 --> 00:20:54.423
And then down here we have this scopes internal property.

396
00:20:55.260 --> 00:20:57.840
And this internal scopes property here

397
00:20:57.840 --> 00:21:00.330
is basically the variable environment

398
00:21:00.330 --> 00:21:01.803
of the booker function.

399
00:21:02.670 --> 00:21:05.610
Now in here we can actually see the closure

400
00:21:05.610 --> 00:21:08.100
coming from secure booking.

401
00:21:08.100 --> 00:21:08.933
Alright?

402
00:21:08.933 --> 00:21:11.910
And so this is where we see the passenger count,

403
00:21:11.910 --> 00:21:14.940
which currently stands at three.

404
00:21:14.940 --> 00:21:17.940
And so this closure here basically

405
00:21:17.940 --> 00:21:21.843
is the variable environment of this secure booking.

406
00:21:23.490 --> 00:21:27.213
So that's the one that is being preserved by the closure.

407
00:21:28.710 --> 00:21:30.360
Alright?

408
00:21:30.360 --> 00:21:31.710
And by the way,

409
00:21:31.710 --> 00:21:35.040
whenever you see these double brackets here,

410
00:21:35.040 --> 00:21:37.800
that means that it is an internal property

411
00:21:37.800 --> 00:21:39.993
which we cannot access from our code.

412
00:21:40.950 --> 00:21:45.330
Alright, this was a long video about closures.

413
00:21:45.330 --> 00:21:47.730
Now in the next lecture we're gonna take a look

414
00:21:47.730 --> 00:21:50.850
at three more examples of closures

415
00:21:50.850 --> 00:21:53.340
and also analyze how they work

416
00:21:53.340 --> 00:21:56.520
because it's really important that you understand

417
00:21:56.520 --> 00:21:58.980
this concept of closures.

418
00:21:58.980 --> 00:22:02.790
It's a feature that's used all the time in JavaScript

419
00:22:02.790 --> 00:22:06.480
and many times even without us realizing

420
00:22:06.480 --> 00:22:08.580
that closures are happening.

421
00:22:08.580 --> 00:22:12.030
So if you want to become confident as a programmer,

422
00:22:12.030 --> 00:22:13.260
you always need to know

423
00:22:13.260 --> 00:22:16.500
how exactly everything in your code works.

424
00:22:16.500 --> 00:22:18.873
And that of course includes closures.

