All language subtitles for 12. Closures

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
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
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranî)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian Download
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu

Original subtitles

1 1

There is an almost mystical feature 2

2

of Java script functions 3

3

that many developers fail to fully understand. 4

4

And what I'm talking about is something called closures. 5

5

So when I asked my students, 6

6

what's the hardest JavaScript concept to understand, 7

7

then many people say that it's closures. 8

8

However, I believe that with the right explanation, 9

9

it's actually not that hard, 10

10

especially when you already understood everything 11

11

that you learned before in this course, 12

12

such as execution context, 13

13

the call stack, and the sculpt chain, 14

14

because closures kind of bring all of these concepts 15

15

together in a beautiful, almost magical way. 16

16

So enough talk, let's see what closures are all about. 17

17

So I'm gonna start by creating a new function here 18

18

called secure booking. 19

19

And it is this function that will create the closure. 20

20

Now, the first thing that I need to tell you about closures 21

21

is that a closure is not a feature that we explicitly use. 22

22

So we don't create closures manually, 23

23

like we create a new array or a new function. 24

24

So a closure simply happens automatically 25

25

in certain situations, we just need 26

26

to recognize those situations. 27

27

And so that's what we're gonna do here in this example. 28

28

So we will create one of those situations 29

29

so that we can then take a look at a closure. 30

30

So anyway, let's now continue writing this example 31

31

and I'm calling this one passengerCount 32

32

and it will start at zero, but we will be 33

33

able to manipulate it. 34

34

And I'm calling this function here, 35

35

secure booking because this passengerCount variable 36

36

cannot be manipulated and accessed from the outside. 37

37

So, and now what's special about this function 38

38

is that it will return a new function. 39

39

And what we do in this function is to update 40

40

the passengerCount variable. 41

41

So the variable that is defined in the parent function. 42

42

So that's important. 43

43

And then let's just log the new passengerCount 44

44

to the console. 45

45

So passengerCount, alright, 46

46

and now let's call the secure booking function 47

47

and then store the result in a variable called Booker. 48

48

And so this is actually pretty similar to what we did 49

49

previously in the lecture of functions 50

50

returning other functions. 51

51

So we have one function here that we call 52

52

and this function will return this new function. 53

53

And so as we call secure booking, 54

54

it will return exactly this function 55

55

and it will then be stored inside this Booker. 56

56

And so this here is gonna be now a function as well, right? 57

57

So let's analyze in detail 58

58

what happens when this line of code here 59

59

is executed using all the concepts 60

60

that we already know about. 61

61

So this is exactly the code that we just wrote. 62

62

Now, before we start running 63

63

the secure booking function down here, 64

64

our code is running in the global execution context. 65

65

And in there, we currently only have 66

66

this secure booking function. 67

67

And so we can also say that the global scope 68

68

now contains secure booking. 69

69

Then when secure booking is actually executed, 70

70

a new execution context is put 71

71

on top of the execution stack. 72

72

Now, remember, each execution context 73

73

has a variable environment, 74

74

which contains all its local variables. 75

75

In this case, it only contains the passengerCount 76

76

set to zero. 77

77

This variable environment is also 78

78

the scope of this function. 79

79

And so the scope chain of this execution context 80

80

looks like this. 81

81

So passengerCount is in the local scope, 82

82

but of course this scope also gets access 83

83

to all variables of the parent's scopes. 84

84

And in this case, just a global scope. 85

85

Anyway, in the next line of the secure booking function, 86

86

a new function is returned and it will be stored 87

87

in the Booker variable. 88

88

So the global context now also contains the Booker variable. 89

89

And now what else happens when 90

90

the secure booking function returns? 91

91

Well, that's right. 92

92

Its execution context pops off the stack and disappears. 93

93

So the secure booking function has done its job 94

94

and has now finished execution. 95

95

It really is gone now and that's important to be aware of 96

96

and to keep in mind. 97

97

And for now, that's actually all we did. 98

98

So all this is nothing new at this point, right? 99

99

All we did was to analyze the call stack 100

100

and the scope chain as we call the secure booking function. 101

101

And this is gonna be important to later on 102

102

understand the closure. 103

103

So as of yet, we didn't see the closure yet. 104

104

All we did was use the knowledge that we already have 105

105

to understand how this Booker function was created, 106

106

because that's gonna be important for the next step. 107

107

So let's now go back to our code 108

108

to actually use the Booker function, 109

109

and then finally see the closure in action. 110

110

So now that we understand how the Booker function 111

111

was created, let's now actually call it here. 112

112

So calling it a couple of times here, and as we can see, 113

113

it doesn't need any arguments. 114

114

There's no list of parameters, right? 115

115

So let's call it here three times 116

116

and now let's reload the page here. 117

117

And indeed we get one, two, three passengers. 118

118

And so what this means is that the Booker function 119

119

was in fact able to increment the passengerCount 120

120

to one, then to two and then to three. 121

121

But now if we think about this, 122

122

then how is this even possible? 123

123

How can the Booker function update 124

124

this passengerCount variable that's defined 125

125

in a secure booking function 126

126

that actually has already finished executing. 127

127

And so, as I just said, 128

128

this function has already finished its execution. 129

129

It is gone. 130

130

So its execution context is no longer on the stack, 131

131

as we just saw in the slide, 132

132

but still this inner function here, 133

133

which is the Booker function, 134

134

is still able to access the passengerCount variable 135

135

that's inside of the Booker function 136

136

that should no longer exist. 137

137

And maybe you can guess that what makes this possible 138

138

is a closure, but before I explain 139

139

exactly how the closure works, 140

140

I want you to appreciate once more, 141

141

how strange this actually is. 142

142

So again, this Booker function here 143

143

is simply a function that exists 144

144

out here in the global environment 145

145

or in the global scope, right? 146

146

And the environment in which the function was created. 147

147

So this year basically, this environment 148

148

is no longer active. 149

149

It is in fact gone. 150

150

But still the Booker function somehow continues 151

151

to have access to the variables 152

152

that were present at the time that the function was created. 153

153

And in particular, this passengerCount variable here. 154

154

And so that's exactly what the closure does. 155

155

So we can say that a closure makes a function 156

156

remember all the variables that existed 157

157

at the function's birthplace essentially, right? 158

158

So we can imagine the secure booking 159

159

as being the birthplace of this function. 160

160

So of the Booker function, essentially. 161

161

And so this function remembers everything at its birthplace, 162

162

by the time it was created. 163

163

And this cannot simply be explained 164

164

with the scope chain alone. 165

165

So we need to also understand the closure. 166

166

And so let me now, really explain how it actually works. 167

167

So this is how we left the call stack 168

168

and the sculpt chain after the last slide. 169

169

And the most important thing to notice here 170

170

is that the execution context of secure booking 171

171

is no longer on call stack, 172

172

because again, this function has finished 173

173

execution long ago. 174

174

So now it's time to finally run the Booker function 175

175

and see exactly what's gonna happen here. 176

176

And note that Booker is really this function here, 177

177

located in the global scope. 178

178

Anyway, the first thing that's gonna happen 179

179

is that a new execution context is created 180

180

and put on top of the call stack 181

181

and the variable environment of this context is emptied 182

182

simply because there are no variables 183

183

declared in this function. 184

184

Now what about the scope chain? 185

185

Well, since Booker is in the global context, 186

186

it's simply a child's scope of the global scope, 187

187

just like this, but maybe now 188

188

you're starting to see the problem. 189

189

So how will the Booker function access 190

190

the passengerCount variable? 191

191

It's nowhere to be found in the scope chain, right? 192

192

So this is where we start to unveil 193

193

the secret of the closure 194

194

and the secret is basically this. 195

195

Any function always has access to the variable environment 196

196

of the execution context in which the function was created. 197

197

Now, in the case of Booker, this function was created. 198

198

It was born in the execution context of secure booking, 199

199

which was popped off the stack previously, remember? 200

200

So, therefore the Booker function 201

201

will get access to this variable environment, 202

202

which contains the passengerCount variable. 203

203

And this is how the function will be able to read 204

204

and manipulate the passengerCount variable. 205

205

And so it's this connection that we call closure. 206

206

So let's say all that again, to make this really clear. 207

207

So a function always has access to the variable environment 208

208

of the execution context in which it was created, 209

209

even after a debt execution context is gone. 210

210

And this last part is really important. 211

211

The closure is then basically this variable environment 212

212

attached to the function, 213

213

exactly as it was at the time and place 214

214

that the function was created. 215

215

And this probably still sounds confusing, but don't worry. 216

216

I have some more familiar analogies in the next slide. 217

217

For now, we are just trying to understand the mechanism 218

218

behind the closure, so how it all works behind the scenes. 219

219

So what matters the most here is that the Booker function 220

220

has access to the passengerCount variable 221

221

because it's basically defined in the scope 222

222

in which the Booker function was actually created. 223

223

So in a sense, the scope chain is actually preserved 224

224

through the closure, even when a scope 225

225

has already been destroyed 226

226

because its execution context is gone. 227

227

This means that even though the execution context 228

228

has actually been destroyed, 229

229

the variable environment somehow keeps living 230

230

somewhere in the engine. 231

231

Now we can say that the Booker function closed over 232

232

its parents scope or over its parent variable environment. 233

233

And this includes all function arguments. 234

234

Even though in this example, we don't have any. 235

235

And now this attached or closed over variable environment 236

236

stays with the function forever. 237

237

It will carry it around and be able to use it forever. 238

238

To make it a bit more digestible, 239

239

we can also say that thanks to the closure, 240

240

a function does not lose connection to variables 241

241

that existed at the function's birthplace. 242

242

That's a bit more intuitive, right? 243

243

But anyway, let's see what happens now 244

244

with execution of the Booker function. 245

245

So the function attempts to increase 246

246

the passengerCount variable. 247

247

However, this variable is not in the current scope. 248

248

And so JavaScript will immediately look into the closure 249

249

and see if it can find the variable there. 250

250

And it does this even before looking at the scope chain. 251

251

For example, if there was a global passengerCount variable 252

252

set to 10, it would still first use the one in the closure. 253

253

So the closure basically has priority over the scope chain. 254

254

And so after running this function, 255

255

the passengerCount becomes one. 256

256

This message is logged. 257

257

And then the execution context is popped off the stack. 258

258

Then execution moves to the next line. 259

259

We get a new execution context and a closure is still there, 260

260

still attached to the function and the value is still one. 261

261

And so now this function executes, 262

262

increasing the passengerCount to two 263

263

and logging a message again. 264

264

Okay, and that's what closures are 265

265

and how they work behind the scenes. 266

266

And I know that this is all quite complex. 267

267

So let me give you a couple different definitions 268

268

of closure now, some more formal ones 269

269

and some more intuitive and maybe easier to grasp. 270

270

And the most formal definition of closure 271

271

is the one we already saw, 272

272

which is that a closure is the closed over variable 273

273

environment of the execution context 274

274

in which a function was created 275

275

even after that execution context is gone, 276

276

or in other words, even after the function 277

277

to which the execution context belongs has returned. 278

278

Next and a bit easier to understand, 279

279

a closure gives a function access to all the variables 280

280

of its parent function. 281

281

So the function in which it is defined 282

282

even after that parent function has returned. 283

283

So the function keeps a reference to its outer scope 284

284

even after that outer scope is gone, 285

285

which basically preserves the scope chain throughout time. 286

286

All right, another definition, 287

287

or let's say analogy is that a closure makes sure 288

288

that a function does never lose connection 289

289

to the variables that existed at the function's birthplace. 290

290

It remembers the variables, 291

291

even after the birthplace is gone. 292

292

It's like a person who doesn't lose connection 293

293

to their hometown. 294

294

In this analogy, the person is the function 295

295

and the hometown is the function's parents scope, 296

296

and the function then doesn't lose the connection 297

297

to the variables stored in this parent's scope. 298

298

And I hope that makes sense. 299

299

Finally, some people like to think of 300

300

this attached variable environment as a backpack. 301

301

So in this analogy, a function has a backpack, 302

302

which it carries around wherever it goes. 303

303

And this backpack contains all the variables 304

304

that were present in the environment 305

305

in which the function was created. 306

306

Then whenever a variable can't be found 307

307

in the function scope, 308

308

JavaScript will look into the backpack 309

309

and take the missing variable from there. 310

310

So kind of similar to the other definitions, 311

311

but maybe a little bit more visual. 312

312

So these are some different ways of defining closure, 313

313

but they all mean the same thing. 314

314

So they all represent the same idea. 315

315

Finally, we need to understand that we do not 316

316

have to create closures manually. 317

317

And this is also what I already touched on 318

318

at the beginning of the lecture. 319

319

So instead, this is something that JavaScript 320

320

does completely automatically, we don't have to do anything. 321

321

Also, there is no way for us to explicitly access 322

322

closed over variables. 323

323

That's because closures are not like a tangible thing. 324

324

They're not like an object or so that we can access. 325

325

So we cannot just reach into a closure 326

326

and take variables from it. 327

327

That's impossible because a closure 328

328

is just an internal property of a function. 329

329

We can observe that a closure happens 330

330

because functions magically keep having access 331

331

to variables that should no longer exist, 332

332

but we cannot directly access these variables. 333

333

However, what we can do is to actually take a look 334

334

at this internal property. 335

335

So at this backpack, so to say, in a console. 336

336

So let's quickly do that before we finish this lecture. 337

337

And we can do this by using console.dir 338

338

and then of the Booker function itself. 339

339

So similar to console.log 340

340

but this one is a bit different. 341

341

And so here we now get this function itself. 342

342

So we can get the arguments, the name property 343

343

that we already took a look at before. 344

344

And then down here, 345

345

we have this scope's internal property. 346

346

And this internal scope's property here 347

347

is basically the variable environment 348

348

of the Booker function. 349

349

Now in here, we can actually see the closure 350

350

coming from secure booking, all right? 351

351

And so this is where we see the passengerCount, 352

352

which currently stands at three. 353

353

And so this closure here basically, 354

354

is the variable environment of this secure booking. 355

355

So that's the one that is being preserved by the closure. 356

356

All right? 357

357

And by the way, whenever you see these double brackets here, 358

358

that means that it is an internal property, 359

359

which we cannot access from our code. 360

360

All right, this was a long video about closures. 361

361

Now in the next lecture, 362

362

we're gonna take a look at three more examples 363

363

of closures and also analyze how they work, 364

364

because it's really important that you understand 365

365

this concept of closures. 366

366

It's a feature that's used all the time in JavaScript 367

367

and many times, even without us realizing 368

368

that closures are happening. 369

369

So if you want to become confident as a programmer, 370

370

you always need to know how exactly 371

371

everything in your code works. 372

372

And that of course includes closures.

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.