1
00:00:01,480 --> 00:00:03,620
<v Jonas>There is an almost mystical feature</v>

2
00:00:03,620 --> 00:00:05,390
of Java script functions

3
00:00:05,390 --> 00:00:09,438
that many developers fail to fully understand.

4
00:00:09,438 --> 00:00:13,572
And what I'm talking about is something called closures.

5
00:00:13,572 --> 00:00:15,440
So when I asked my students,

6
00:00:15,440 --> 00:00:18,753
what's the hardest JavaScript concept to understand,

7
00:00:18,753 --> 00:00:22,290
then many people say that it's closures.

8
00:00:22,290 --> 00:00:25,400
However, I believe that with the right explanation,

9
00:00:25,400 --> 00:00:27,830
it's actually not that hard,

10
00:00:27,830 --> 00:00:30,740
especially when you already understood everything

11
00:00:30,740 --> 00:00:33,020
that you learned before in this course,

12
00:00:33,020 --> 00:00:35,120
such as execution context,

13
00:00:35,120 --> 00:00:37,800
the call stack, and the sculpt chain,

14
00:00:37,800 --> 00:00:40,810
because closures kind of bring all of these concepts

15
00:00:40,810 --> 00:00:45,370
together in a beautiful, almost magical way.

16
00:00:45,370 --> 00:00:49,463
So enough talk, let's see what closures are all about.

17
00:00:51,400 --> 00:00:54,561
So I'm gonna start by creating a new function here

18
00:00:54,561 --> 00:00:57,853
called secure booking.

19
00:01:00,450 --> 00:01:04,810
And it is this function that will create the closure.

20
00:01:04,810 --> 00:01:08,036
Now, the first thing that I need to tell you about closures

21
00:01:08,036 --> 00:01:13,036
is that a closure is not a feature that we explicitly use.

22
00:01:13,710 --> 00:01:16,292
So we don't create closures manually,

23
00:01:16,292 --> 00:01:20,310
like we create a new array or a new function.

24
00:01:20,310 --> 00:01:22,741
So a closure simply happens automatically

25
00:01:22,741 --> 00:01:25,540
in certain situations, we just need

26
00:01:25,540 --> 00:01:28,310
to recognize those situations.

27
00:01:28,310 --> 00:01:31,600
And so that's what we're gonna do here in this example.

28
00:01:31,600 --> 00:01:33,908
So we will create one of those situations

29
00:01:33,908 --> 00:01:37,773
so that we can then take a look at a closure.

30
00:01:38,730 --> 00:01:41,430
So anyway, let's now continue writing this example

31
00:01:43,730 --> 00:01:45,110
and I'm calling this one passengerCount

32
00:01:46,530 --> 00:01:49,410
and it will start at zero, but we will be

33
00:01:49,410 --> 00:01:51,720
able to manipulate it.

34
00:01:51,720 --> 00:01:53,240
And I'm calling this function here,

35
00:01:53,240 --> 00:01:55,947
secure booking because this passengerCount variable

36
00:01:55,947 --> 00:02:00,947
cannot be manipulated and accessed from the outside.

37
00:02:02,690 --> 00:02:05,360
So, and now what's special about this function

38
00:02:05,360 --> 00:02:09,163
is that it will return a new function.

39
00:02:12,600 --> 00:02:15,773
And what we do in this function is to update

40
00:02:15,773 --> 00:02:18,303
the passengerCount variable.

41
00:02:19,220 --> 00:02:22,803
So the variable that is defined in the parent function.

42
00:02:23,800 --> 00:02:25,670
So that's important.

43
00:02:25,670 --> 00:02:28,810
And then let's just log the new passengerCount

44
00:02:28,810 --> 00:02:29,943
to the console.

45
00:02:32,800 --> 00:02:37,480
So passengerCount, alright,

46
00:02:37,480 --> 00:02:41,130
and now let's call the secure booking function

47
00:02:41,130 --> 00:02:44,333
and then store the result in a variable called Booker.

48
00:02:46,820 --> 00:02:49,100
And so this is actually pretty similar to what we did

49
00:02:49,100 --> 00:02:52,600
previously in the lecture of functions

50
00:02:52,600 --> 00:02:54,490
returning other functions.

51
00:02:54,490 --> 00:02:56,752
So we have one function here that we call

52
00:02:56,752 --> 00:03:00,970
and this function will return this new function.

53
00:03:00,970 --> 00:03:02,669
And so as we call secure booking,

54
00:03:02,669 --> 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,673
And so this here is gonna be now a function as well, right?

57
00:03:13,660 --> 00:03:15,290
So let's analyze in detail

58
00:03:15,290 --> 00:03:17,660
what happens when this line of code here

59
00:03:17,660 --> 00:03:20,180
is executed using all the concepts

60
00:03:20,180 --> 00:03:21,633
that we already know about.

61
00:03:23,130 --> 00:03:26,700
So this is exactly the code that we just wrote.

62
00:03:26,700 --> 00:03:28,410
Now, before we start running

63
00:03:28,410 --> 00:03:30,760
the secure booking function down here,

64
00:03:30,760 --> 00:03:34,720
our code is running in the global execution context.

65
00:03:34,720 --> 00:03:36,970
And in there, we currently only have

66
00:03:36,970 --> 00:03:39,180
this secure booking function.

67
00:03:39,180 --> 00:03:42,260
And so we can also say that the global scope

68
00:03:42,260 --> 00:03:44,970
now contains secure booking.

69
00:03:44,970 --> 00:03:48,530
Then when secure booking is actually executed,

70
00:03:48,530 --> 00:03:50,718
a new execution context is put

71
00:03:50,718 --> 00:03:53,820
on top of the execution stack.

72
00:03:53,820 --> 00:03:56,233
Now, remember, each execution context

73
00:03:56,233 --> 00:03:58,730
has a variable environment,

74
00:03:58,730 --> 00:04:01,900
which contains all its local variables.

75
00:04:01,900 --> 00:04:04,831
In this case, it only contains the passengerCount

76
00:04:04,831 --> 00:04:06,363
set to zero.

77
00:04:07,200 --> 00:04:09,120
This variable environment is also

78
00:04:09,120 --> 00:04:11,470
the scope of this function.

79
00:04:11,470 --> 00:04:14,441
And so the scope chain of this execution context

80
00:04:14,441 --> 00:04:16,191
looks like this.

81
00:04:16,191 --> 00:04:19,315
So passengerCount is in the local scope,

82
00:04:19,315 --> 00:04:22,480
but of course this scope also gets access

83
00:04:22,480 --> 00:04:25,540
to all variables of the parent's scopes.

84
00:04:25,540 --> 00:04:28,960
And in this case, just a global scope.

85
00:04:28,960 --> 00:04:32,161
Anyway, in the next line of the secure booking function,

86
00:04:32,161 --> 00:04:36,060
a new function is returned and it will be stored

87
00:04:36,060 --> 00:04:37,960
in the Booker variable.

88
00:04:37,960 --> 00:04:42,710
So the global context now also contains the Booker variable.

89
00:04:42,710 --> 00:04:44,710
And now what else happens when

90
00:04:44,710 --> 00:04:47,600
the secure booking function returns?

91
00:04:47,600 --> 00:04:48,990
Well, that's right.

92
00:04:48,990 --> 00:04:53,268
Its execution context pops off the stack and disappears.

93
00:04:53,268 --> 00:04:56,740
So the secure booking function has done its job

94
00:04:56,740 --> 00:04:59,700
and has now finished execution.

95
00:04:59,700 --> 00:05:03,980
It really is gone now and that's important to be aware of

96
00:05:03,980 --> 00:05:05,770
and to keep in mind.

97
00:05:05,770 --> 00:05:08,860
And for now, that's actually all we did.

98
00:05:08,860 --> 00:05:11,914
So all this is nothing new at this point, right?

99
00:05:11,914 --> 00:05:14,530
All we did was to analyze the call stack

100
00:05:14,530 --> 00:05:18,620
and the scope chain as we call the secure booking function.

101
00:05:18,620 --> 00:05:20,870
And this is gonna be important to later on

102
00:05:20,870 --> 00:05:22,950
understand the closure.

103
00:05:22,950 --> 00:05:26,320
So as of yet, we didn't see the closure yet.

104
00:05:26,320 --> 00:05:29,357
All we did was use the knowledge that we already have

105
00:05:29,357 --> 00:05:33,600
to understand how this Booker function was created,

106
00:05:33,600 --> 00:05:37,610
because that's gonna be important for the next step.

107
00:05:37,610 --> 00:05:39,357
So let's now go back to our code

108
00:05:39,357 --> 00:05:42,400
to actually use the Booker function,

109
00:05:42,400 --> 00:05:45,313
and then finally see the closure in action.

110
00:05:46,950 --> 00:05:49,880
So now that we understand how the Booker function

111
00:05:49,880 --> 00:05:53,003
was created, let's now actually call it here.

112
00:05:54,860 --> 00:05:58,790
So calling it a couple of times here, and as we can see,

113
00:05:58,790 --> 00:06:00,930
it doesn't need any arguments.

114
00:06:00,930 --> 00:06:03,613
There's no list of parameters, right?

115
00:06:05,150 --> 00:06:07,080
So let's call it here three times

116
00:06:09,280 --> 00:06:13,120
and now let's reload the page here.

117
00:06:13,120 --> 00:06:17,670
And indeed we get one, two, three passengers.

118
00:06:17,670 --> 00:06:20,682
And so what this means is that the Booker function

119
00:06:20,682 --> 00:06:24,910
was in fact able to increment the passengerCount

120
00:06:24,910 --> 00:06:28,810
to one, then to two and then to three.

121
00:06:28,810 --> 00:06:30,920
But now if we think about this,

122
00:06:30,920 --> 00:06:33,300
then how is this even possible?

123
00:06:33,300 --> 00:06:35,143
How can the Booker function update

124
00:06:35,143 --> 00:06:38,196
this passengerCount variable that's defined

125
00:06:38,196 --> 00:06:40,200
in a secure booking function

126
00:06:40,200 --> 00:06:44,030
that actually has already finished executing.

127
00:06:44,030 --> 00:06:45,670
And so, as I just said,

128
00:06:45,670 --> 00:06:48,970
this function has already finished its execution.

129
00:06:48,970 --> 00:06:50,090
It is gone.

130
00:06:50,090 --> 00:06:53,980
So its execution context is no longer on the stack,

131
00:06:53,980 --> 00:06:56,290
as we just saw in the slide,

132
00:06:56,290 --> 00:06:59,030
but still this inner function here,

133
00:06:59,030 --> 00:07:01,180
which is the Booker function,

134
00:07:01,180 --> 00:07:04,911
is still able to access the passengerCount variable

135
00:07:04,911 --> 00:07:07,700
that's inside of the Booker function

136
00:07:07,700 --> 00:07:10,380
that should no longer exist.

137
00:07:10,380 --> 00:07:13,708
And maybe you can guess that what makes this possible

138
00:07:13,708 --> 00:07:17,120
is a closure, but before I explain

139
00:07:17,120 --> 00:07:19,400
exactly how the closure works,

140
00:07:19,400 --> 00:07:21,760
I want you to appreciate once more,

141
00:07:21,760 --> 00:07:24,870
how strange this actually is.

142
00:07:24,870 --> 00:07:27,529
So again, this Booker function here

143
00:07:27,529 --> 00:07:30,150
is simply a function that exists

144
00:07:30,150 --> 00:07:32,193
out here in the global environment

145
00:07:32,193 --> 00:07:35,200
or in the global scope, right?

146
00:07:35,200 --> 00:07:38,383
And the environment in which the function was created.

147
00:07:38,383 --> 00:07:41,870
So this year basically, this environment

148
00:07:41,870 --> 00:07:44,150
is no longer active.

149
00:07:44,150 --> 00:07:46,080
It is in fact gone.

150
00:07:46,080 --> 00:07:49,110
But still the Booker function somehow continues

151
00:07:49,110 --> 00:07:50,980
to have access to the variables

152
00:07:50,980 --> 00:07:55,300
that were present at the time that the function was created.

153
00:07:55,300 --> 00:07:59,300
And in particular, this passengerCount variable here.

154
00:07:59,300 --> 00:08:02,237
And so that's exactly what the closure does.

155
00:08:02,237 --> 00:08:05,520
So we can say that a closure makes a function

156
00:08:05,520 --> 00:08:08,466
remember all the variables that existed

157
00:08:08,466 --> 00:08:12,490
at the function's birthplace essentially, right?

158
00:08:12,490 --> 00:08:15,960
So we can imagine the secure booking

159
00:08:15,960 --> 00:08:19,510
as being the birthplace of this function.

160
00:08:19,510 --> 00:08:22,070
So of the Booker function, essentially.

161
00:08:22,070 --> 00:08:25,829
And so this function remembers everything at its birthplace,

162
00:08:25,829 --> 00:08:28,540
by the time it was created.

163
00:08:28,540 --> 00:08:31,000
And this cannot simply be explained

164
00:08:31,000 --> 00:08:33,160
with the scope chain alone.

165
00:08:33,160 --> 00:08:35,769
So we need to also understand the closure.

166
00:08:35,769 --> 00:08:39,743
And so let me now, really explain how it actually works.

167
00:08:40,940 --> 00:08:43,550
So this is how we left the call stack

168
00:08:43,550 --> 00:08:46,820
and the sculpt chain after the last slide.

169
00:08:46,820 --> 00:08:49,310
And the most important thing to notice here

170
00:08:49,310 --> 00:08:52,322
is that the execution context of secure booking

171
00:08:52,322 --> 00:08:55,140
is no longer on call stack,

172
00:08:55,140 --> 00:08:58,210
because again, this function has finished

173
00:08:58,210 --> 00:09:00,600
execution long ago.

174
00:09:00,600 --> 00:09:04,129
So now it's time to finally run the Booker function

175
00:09:04,129 --> 00:09:07,520
and see exactly what's gonna happen here.

176
00:09:07,520 --> 00:09:11,540
And note that Booker is really this function here,

177
00:09:11,540 --> 00:09:13,583
located in the global scope.

178
00:09:14,540 --> 00:09:17,016
Anyway, the first thing that's gonna happen

179
00:09:17,016 --> 00:09:20,382
is that a new execution context is created

180
00:09:20,382 --> 00:09:23,410
and put on top of the call stack

181
00:09:23,410 --> 00:09:27,036
and the variable environment of this context is emptied

182
00:09:27,036 --> 00:09:29,480
simply because there are no variables

183
00:09:29,480 --> 00:09:31,990
declared in this function.

184
00:09:31,990 --> 00:09:34,680
Now what about the scope chain?

185
00:09:34,680 --> 00:09:37,539
Well, since Booker is in the global context,

186
00:09:37,539 --> 00:09:41,270
it's simply a child's scope of the global scope,

187
00:09:41,270 --> 00:09:44,480
just like this, but maybe now

188
00:09:44,480 --> 00:09:46,870
you're starting to see the problem.

189
00:09:46,870 --> 00:09:49,509
So how will the Booker function access

190
00:09:49,509 --> 00:09:52,510
the passengerCount variable?

191
00:09:52,510 --> 00:09:56,460
It's nowhere to be found in the scope chain, right?

192
00:09:56,460 --> 00:09:58,580
So this is where we start to unveil

193
00:09:58,580 --> 00:10:01,330
the secret of the closure

194
00:10:01,330 --> 00:10:04,100
and the secret is basically this.

195
00:10:04,100 --> 00:10:07,541
Any function always has access to the variable environment

196
00:10:07,541 --> 00:10:12,183
of the execution context in which the function was created.

197
00:10:13,040 --> 00:10:16,719
Now, in the case of Booker, this function was created.

198
00:10:16,719 --> 00:10:21,719
It was born in the execution context of secure booking,

199
00:10:22,060 --> 00:10:26,360
which was popped off the stack previously, remember?

200
00:10:26,360 --> 00:10:28,920
So, therefore the Booker function

201
00:10:28,920 --> 00:10:32,470
will get access to this variable environment,

202
00:10:32,470 --> 00:10:35,623
which contains the passengerCount variable.

203
00:10:35,623 --> 00:10:39,170
And this is how the function will be able to read

204
00:10:39,170 --> 00:10:42,840
and manipulate the passengerCount variable.

205
00:10:42,840 --> 00:10:46,273
And so it's this connection that we call closure.

206
00:10:47,690 --> 00:10:51,700
So let's say all that again, to make this really clear.

207
00:10:51,700 --> 00:10:55,658
So a function always has access to the variable environment

208
00:10:55,658 --> 00:10:59,980
of the execution context in which it was created,

209
00:10:59,980 --> 00:11:03,920
even after a debt execution context is gone.

210
00:11:03,920 --> 00:11:06,800
And this last part is really important.

211
00:11:06,800 --> 00:11:10,400
The closure is then basically this variable environment

212
00:11:10,400 --> 00:11:12,500
attached to the function,

213
00:11:12,500 --> 00:11:15,530
exactly as it was at the time and place

214
00:11:15,530 --> 00:11:18,110
that the function was created.

215
00:11:18,110 --> 00:11:22,290
And this probably still sounds confusing, but don't worry.

216
00:11:22,290 --> 00:11:26,025
I have some more familiar analogies in the next slide.

217
00:11:26,025 --> 00:11:29,397
For now, we are just trying to understand the mechanism

218
00:11:29,397 --> 00:11:33,525
behind the closure, so how it all works behind the scenes.

219
00:11:33,525 --> 00:11:37,610
So what matters the most here is that the Booker function

220
00:11:37,610 --> 00:11:40,472
has access to the passengerCount variable

221
00:11:40,472 --> 00:11:43,435
because it's basically defined in the scope

222
00:11:43,435 --> 00:11:47,141
in which the Booker function was actually created.

223
00:11:47,141 --> 00:11:51,068
So in a sense, the scope chain is actually preserved

224
00:11:51,068 --> 00:11:54,210
through the closure, even when a scope

225
00:11:54,210 --> 00:11:56,260
has already been destroyed

226
00:11:56,260 --> 00:11:59,384
because its execution context is gone.

227
00:11:59,384 --> 00:12:03,080
This means that even though the execution context

228
00:12:03,080 --> 00:12:04,742
has actually been destroyed,

229
00:12:04,742 --> 00:12:07,659
the variable environment somehow keeps living

230
00:12:07,659 --> 00:12:10,210
somewhere in the engine.

231
00:12:10,210 --> 00:12:13,820
Now we can say that the Booker function closed over

232
00:12:13,820 --> 00:12:18,272
its parents scope or over its parent variable environment.

233
00:12:18,272 --> 00:12:21,080
And this includes all function arguments.

234
00:12:21,080 --> 00:12:24,650
Even though in this example, we don't have any.

235
00:12:24,650 --> 00:12:28,656
And now this attached or closed over variable environment

236
00:12:28,656 --> 00:12:31,920
stays with the function forever.

237
00:12:31,920 --> 00:12:36,350
It will carry it around and be able to use it forever.

238
00:12:36,350 --> 00:12:38,750
To make it a bit more digestible,

239
00:12:38,750 --> 00:12:41,435
we can also say that thanks to the closure,

240
00:12:41,435 --> 00:12:45,015
a function does not lose connection to variables

241
00:12:45,015 --> 00:12:48,120
that existed at the function's birthplace.

242
00:12:48,120 --> 00:12:50,619
That's a bit more intuitive, right?

243
00:12:50,619 --> 00:12:53,520
But anyway, let's see what happens now

244
00:12:53,520 --> 00:12:56,890
with execution of the Booker function.

245
00:12:56,890 --> 00:12:59,490
So the function attempts to increase

246
00:12:59,490 --> 00:13:01,830
the passengerCount variable.

247
00:13:01,830 --> 00:13:05,980
However, this variable is not in the current scope.

248
00:13:05,980 --> 00:13:09,454
And so JavaScript will immediately look into the closure

249
00:13:09,454 --> 00:13:12,830
and see if it can find the variable there.

250
00:13:12,830 --> 00:13:16,677
And it does this even before looking at the scope chain.

251
00:13:16,677 --> 00:13:20,570
For example, if there was a global passengerCount variable

252
00:13:20,570 --> 00:13:25,016
set to 10, it would still first use the one in the closure.

253
00:13:25,016 --> 00:13:30,000
So the closure basically has priority over the scope chain.

254
00:13:30,000 --> 00:13:31,970
And so after running this function,

255
00:13:31,970 --> 00:13:34,190
the passengerCount becomes one.

256
00:13:34,190 --> 00:13:35,940
This message is logged.

257
00:13:35,940 --> 00:13:40,350
And then the execution context is popped off the stack.

258
00:13:40,350 --> 00:13:42,990
Then execution moves to the next line.

259
00:13:42,990 --> 00:13:46,990
We get a new execution context and a closure is still there,

260
00:13:46,990 --> 00:13:51,790
still attached to the function and the value is still one.

261
00:13:51,790 --> 00:13:53,849
And so now this function executes,

262
00:13:53,849 --> 00:13:56,546
increasing the passengerCount to two

263
00:13:56,546 --> 00:13:59,790
and logging a message again.

264
00:13:59,790 --> 00:14:02,670
Okay, and that's what closures are

265
00:14:02,670 --> 00:14:04,942
and how they work behind the scenes.

266
00:14:04,942 --> 00:14:08,720
And I know that this is all quite complex.

267
00:14:08,720 --> 00:14:11,420
So let me give you a couple different definitions

268
00:14:11,420 --> 00:14:14,313
of closure now, some more formal ones

269
00:14:14,313 --> 00:14:19,080
and some more intuitive and maybe easier to grasp.

270
00:14:19,080 --> 00:14:21,750
And the most formal definition of closure

271
00:14:21,750 --> 00:14:23,690
is the one we already saw,

272
00:14:23,690 --> 00:14:27,320
which is that a closure is the closed over variable

273
00:14:27,320 --> 00:14:30,060
environment of the execution context

274
00:14:30,060 --> 00:14:32,385
in which a function was created

275
00:14:32,385 --> 00:14:36,700
even after that execution context is gone,

276
00:14:36,700 --> 00:14:39,610
or in other words, even after the function

277
00:14:39,610 --> 00:14:43,563
to which the execution context belongs has returned.

278
00:14:44,500 --> 00:14:47,138
Next and a bit easier to understand,

279
00:14:47,138 --> 00:14:51,400
a closure gives a function access to all the variables

280
00:14:51,400 --> 00:14:53,340
of its parent function.

281
00:14:53,340 --> 00:14:56,860
So the function in which it is defined

282
00:14:56,860 --> 00:15:00,900
even after that parent function has returned.

283
00:15:00,900 --> 00:15:04,224
So the function keeps a reference to its outer scope

284
00:15:04,224 --> 00:15:07,530
even after that outer scope is gone,

285
00:15:07,530 --> 00:15:11,193
which basically preserves the scope chain throughout time.

286
00:15:12,200 --> 00:15:14,230
All right, another definition,

287
00:15:14,230 --> 00:15:18,500
or let's say analogy is that a closure makes sure

288
00:15:18,500 --> 00:15:21,320
that a function does never lose connection

289
00:15:21,320 --> 00:15:25,310
to the variables that existed at the function's birthplace.

290
00:15:25,310 --> 00:15:27,070
It remembers the variables,

291
00:15:27,070 --> 00:15:30,200
even after the birthplace is gone.

292
00:15:30,200 --> 00:15:32,900
It's like a person who doesn't lose connection

293
00:15:32,900 --> 00:15:35,030
to their hometown.

294
00:15:35,030 --> 00:15:38,233
In this analogy, the person is the function

295
00:15:38,233 --> 00:15:42,040
and the hometown is the function's parents scope,

296
00:15:42,040 --> 00:15:44,520
and the function then doesn't lose the connection

297
00:15:44,520 --> 00:15:48,400
to the variables stored in this parent's scope.

298
00:15:48,400 --> 00:15:51,013
And I hope that makes sense.

299
00:15:51,870 --> 00:15:54,236
Finally, some people like to think of

300
00:15:54,236 --> 00:15:58,540
this attached variable environment as a backpack.

301
00:15:58,540 --> 00:16:02,130
So in this analogy, a function has a backpack,

302
00:16:02,130 --> 00:16:05,470
which it carries around wherever it goes.

303
00:16:05,470 --> 00:16:08,250
And this backpack contains all the variables

304
00:16:08,250 --> 00:16:10,670
that were present in the environment

305
00:16:10,670 --> 00:16:13,300
in which the function was created.

306
00:16:13,300 --> 00:16:16,000
Then whenever a variable can't be found

307
00:16:16,000 --> 00:16:17,720
in the function scope,

308
00:16:17,720 --> 00:16:20,092
JavaScript will look into the backpack

309
00:16:20,092 --> 00:16:23,460
and take the missing variable from there.

310
00:16:23,460 --> 00:16:26,358
So kind of similar to the other definitions,

311
00:16:26,358 --> 00:16:30,110
but maybe a little bit more visual.

312
00:16:30,110 --> 00:16:34,050
So these are some different ways of defining closure,

313
00:16:34,050 --> 00:16:36,350
but they all mean the same thing.

314
00:16:36,350 --> 00:16:38,973
So they all represent the same idea.

315
00:16:39,890 --> 00:16:43,010
Finally, we need to understand that we do not

316
00:16:43,010 --> 00:16:45,520
have to create closures manually.

317
00:16:45,520 --> 00:16:47,859
And this is also what I already touched on

318
00:16:47,859 --> 00:16:50,690
at the beginning of the lecture.

319
00:16:50,690 --> 00:16:53,880
So instead, this is something that JavaScript

320
00:16:53,880 --> 00:16:58,520
does completely automatically, we don't have to do anything.

321
00:16:58,520 --> 00:17:02,430
Also, there is no way for us to explicitly access

322
00:17:02,430 --> 00:17:04,500
closed over variables.

323
00:17:04,500 --> 00:17:08,290
That's because closures are not like a tangible thing.

324
00:17:08,290 --> 00:17:12,130
They're not like an object or so that we can access.

325
00:17:12,130 --> 00:17:14,544
So we cannot just reach into a closure

326
00:17:14,544 --> 00:17:17,040
and take variables from it.

327
00:17:17,040 --> 00:17:19,660
That's impossible because a closure

328
00:17:19,660 --> 00:17:23,520
is just an internal property of a function.

329
00:17:23,520 --> 00:17:26,073
We can observe that a closure happens

330
00:17:26,073 --> 00:17:29,400
because functions magically keep having access

331
00:17:29,400 --> 00:17:32,730
to variables that should no longer exist,

332
00:17:32,730 --> 00:17:36,850
but we cannot directly access these variables.

333
00:17:36,850 --> 00:17:40,182
However, what we can do is to actually take a look

334
00:17:40,182 --> 00:17:42,440
at this internal property.

335
00:17:42,440 --> 00:17:46,960
So at this backpack, so to say, in a console.

336
00:17:46,960 --> 00:17:50,183
So let's quickly do that before we finish this lecture.

337
00:17:51,930 --> 00:17:55,320
And we can do this by using console.dir

338
00:17:58,282 --> 00:18:01,270
and then of the Booker function itself.

339
00:18:01,270 --> 00:18:03,440
So similar to console.log

340
00:18:03,440 --> 00:18:06,100
but this one is a bit different.

341
00:18:06,100 --> 00:18:09,433
And so here we now get this function itself.

342
00:18:11,020 --> 00:18:14,290
So we can get the arguments, the name property

343
00:18:14,290 --> 00:18:17,170
that we already took a look at before.

344
00:18:17,170 --> 00:18:18,003
And then down here,

345
00:18:18,003 --> 00:18:20,993
we have this scope's internal property.

346
00:18:21,860 --> 00:18:24,430
And this internal scope's property here

347
00:18:24,430 --> 00:18:26,930
is basically the variable environment

348
00:18:26,930 --> 00:18:28,393
of the Booker function.

349
00:18:29,270 --> 00:18:31,774
Now in here, we can actually see the closure

350
00:18:31,774 --> 00:18:35,460
coming from secure booking, all right?

351
00:18:35,460 --> 00:18:38,520
And so this is where we see the passengerCount,

352
00:18:38,520 --> 00:18:41,540
which currently stands at three.

353
00:18:41,540 --> 00:18:44,267
And so this closure here basically,

354
00:18:44,267 --> 00:18:48,453
is the variable environment of this secure booking.

355
00:18:50,100 --> 00:18:53,793
So that's the one that is being preserved by the closure.

356
00:18:55,340 --> 00:18:56,970
All right?

357
00:18:56,970 --> 00:19:01,650
And by the way, whenever you see these double brackets here,

358
00:19:01,650 --> 00:19:04,390
that means that it is an internal property,

359
00:19:04,390 --> 00:19:06,603
which we cannot access from our code.

360
00:19:07,570 --> 00:19:11,920
All right, this was a long video about closures.

361
00:19:11,920 --> 00:19:13,200
Now in the next lecture,

362
00:19:13,200 --> 00:19:16,080
we're gonna take a look at three more examples

363
00:19:16,080 --> 00:19:19,940
of closures and also analyze how they work,

364
00:19:19,940 --> 00:19:23,120
because it's really important that you understand

365
00:19:23,120 --> 00:19:25,600
this concept of closures.

366
00:19:25,600 --> 00:19:29,071
It's a feature that's used all the time in JavaScript

367
00:19:29,071 --> 00:19:33,080
and many times, even without us realizing

368
00:19:33,080 --> 00:19:35,180
that closures are happening.

369
00:19:35,180 --> 00:19:38,272
So if you want to become confident as a programmer,

370
00:19:38,272 --> 00:19:40,730
you always need to know how exactly

371
00:19:40,730 --> 00:19:43,100
everything in your code works.

372
00:19:43,100 --> 00:19:45,453
And that of course includes closures.

