All language subtitles for 12. Closures

af Afrikaans
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bn Bengali
bs Bosnian
bg Bulgarian
ca Catalan
ceb Cebuano
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
tl Filipino
fi Finnish
fr French
fy Frisian
gl Galician
ka Georgian
de German
el Greek
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
km Khmer
ko Korean
ku Kurdish (Kurmanji)
ky Kyrgyz
lo Lao
la Latin
lv Latvian
lt Lithuanian
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mn Mongolian
my Myanmar (Burmese)
ne Nepali
no Norwegian
ps Pashto
fa Persian Download
pl Polish
pt Portuguese
pa Punjabi
ro Romanian
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
st Sesotho
sn Shona
sd Sindhi
si Sinhala
sk Slovak
sl Slovenian
so Somali
es Spanish
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
te Telugu
th Thai
tr Turkish
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu
or Odia (Oriya)
rw Kinyarwanda
tk Turkmen
tt Tatar
ug Uyghur
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.