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