Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
French
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranรฎ)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
1 1
Now it's time to see scoping in action 2
2
in a semi complex example, 3
3
to make sure that you really get 4
4
the super important concept. 5
5
And as always, 6
6
let's start by opening up a new VS Code window 7
7
with (mumbles) starter files. 8
8
So that's already here at my desktop. 9
9
And again, 10
10
I have the prettier configuration here. 11
11
The index is not really important here. 12
12
And so let's just start writing 13
13
some JavaScript code here. 14
14
And I'm gonna start by writing a 15
15
simple calcAge function. 16
16
And this time let's actually use a function declaration. 17
17
Not that it matters. 18
18
But just to have some diversity, 19
19
and not always create the same type of function. 20
20
So calcAge, 21
21
which is gonna receive a birth year. 22
22
And then all this function does 23
23
is to calculate an age. 24
24
And so this is nothing new at this point. 25
25
So the current year, 26
26
minus the birth year. 27
27
Then let's also 28
28
return that age here. 29
29
And so this calcAge function here is, 30
30
as we learned in the last lecture, 31
31
defined in a global scope. 32
32
And that's because it is 33
33
here in the top level code, right? 34
34
Also, this function here creates its own scope. 35
35
And that scope is gonna be equivalent 36
36
to the variable environment 37
37
of its execution context. 38
38
So that's all the stuff we learned 39
39
over the past couple of lectures. 40
40
And now let's create a global variable here. 41
41
So I'm gonna call that one 42
42
first, name. 43
43
And now let's actually call the function 44
44
so calcAge, 45
45
with 1991. 46
46
And then here inside of this calcAge function, 47
47
I will log first name to the console. 48
48
So first name. 49
49
Now as you see, 50
50
this first name variable is not actually in this scope 51
51
of the calcAge function. 52
52
However, it is a global variable 53
53
that we defined out here. 54
54
And so therefore, 55
55
through the scope chain, 56
56
it's gonna be made available 57
57
also inside of this scope. 58
58
So inside of this function, right? 59
59
So let's just execute this code here, 60
60
just to see that it actually works. 61
61
And then we're gonna explain a little bit more. 62
62
So live server. 63
63
And so here we go. 64
64
Let's open up the console. 65
65
Let's reload to get rid of this error. 66
66
And okay. 67
67
So you see that indeed, 68
68
Jonas here was printed to the console, 69
69
which is the first name variable. 70
70
And so when this line of code here was executed, 71
71
JavaScript did not find this variable in the scope. 72
72
And so it did a variable lookup, 73
73
where it looked up in the scope chain 74
74
to see if it found the variable there. 75
75
And indeed, the parent scope 76
76
of the calcAge function is the global scope. 77
77
And the first name variable is in there, 78
78
and therefore JavaScript could then use that. 79
79
Now here, if we tried, 80
80
for example just name, 81
81
then JavaScript would also do a lookup, 82
82
but it would not find this variable in the global scope. 83
83
And therefore, we would get an error. 84
84
Now with this variable, 85
85
actually we would get no error. 86
86
As I explained to you in the beginning, 87
87
this is kind of a special 88
88
variable name that we should not use. 89
89
So let's say I used last name. 90
90
And so again, this variable 91
91
is nowhere to be found. 92
92
So even by doing a look up 93
93
into the parent scope, 94
94
and so now when I saved this, 95
95
then I get this last name is not define error. 96
96
Okay? 97
97
And so going back here to first name, 98
98
then of course, 99
99
everything works just the same. 100
100
And that is true, 101
101
even though this variable here 102
102
was actually defined after the calcAge function. 103
103
But that's not a problem at all. 104
104
Because remember that the code in the function 105
105
is only executed once it's actually called. 106
106
And so that happens after 107
107
the declaration of the first name variable. 108
108
So right here. 109
109
And so at this point in the code, 110
110
the first name variable is already 111
111
in the global execution variable environment. 112
112
So in the global scope, ready to be used. 113
113
Okay, but let's actually get rid of this here. 114
114
And let's create another function inside of this function. 115
115
So function, printAge 116
116
and this will print a nice string to the console. 117
117
And as you also know already, 118
118
it also creates a new scope. 119
119
And let's create an output variable, 120
120
which is gonna be the string 121
121
that we will build here. 122
122
So output equals, 123
123
you are 124
124
the age, 125
125
and I forgot the curly braces 126
126
born in 127
127
birth year. 128
128
And then we simply log that message to the console. 129
129
And now to actually see this result here, 130
130
we need to, of course, call the function. 131
131
So let's do that right here. 132
132
So printAge. 133
133
And now we get a string with all the data 134
134
that we actually computed, 135
135
and it works just fine. 136
136
So we get the age that was calculated here, 137
137
and also the birth year 138
138
that was passed into this function. 139
139
And so here again, 140
140
we see the magic of the scope chain in action. 141
141
So once again, 142
142
the engine as it is executing this printAge function 143
143
is trying to access 144
144
or is trying to find the age variable 145
145
in the current scope, 146
146
however it cannot find it there. 147
147
And so therefore, 148
148
it goes to the parent scope, 149
149
where it will then find 150
150
this age variable of course, 151
151
that we created here. 152
152
And the same is true for the birth year variable, 153
153
because for scoping 154
154
the parameter of a function 155
155
work just like normal variables. 156
156
And also remember that we said 157
157
that the scope of a variable 158
158
is the entire region of the code 159
159
in which the variable is accessible. 160
160
So for example, 161
161
the scope of the age variable 162
162
is all of this area here. 163
163
So everywhere here, 164
164
the age variable is accessible. 165
165
So of course, 166
166
in the calcAge function, where it was defined, 167
167
and then also in all the child scopes, 168
168
so all the inner scopes, okay? 169
169
But of course, age is not accessible outside 170
170
of the calcAge scope. 171
171
So let me demonstrate that here. 172
172
So here, we will not be able 173
173
to access the age variable. 174
174
And that is because as I mentioned, 175
175
the scope chain is a one way street. 176
176
So only an inner scope 177
177
can have access to the variables of its outer scope, 178
178
but not the other way around. 179
179
So now here we are in the outer scope, 180
180
and we cannot have access to the variables 181
181
of a child scope, 182
182
which the scope of the calcAge function here 183
183
surely is, okay? 184
184
And the same goes for functions again. 185
185
And so we cannot call the printAge function out here, 186
186
for the same reason. 187
187
Let's comment out this one. 188
188
And so now we get printAge is not defined. 189
189
Okay? 190
190
So here in the global scope, 191
191
we do not have access to any variables defined 192
192
in any other scope. 193
193
Now, all right? 194
194
And here, let's actually take it to the next level, 195
195
and also include the name of the person. 196
196
So let's say, first name. 197
197
And let's try this now. 198
198
And indeed, it does have access 199
199
to the first name variable. 200
200
And so here, 201
201
the engine is doing an even bigger, 202
202
or a longer variable lookup. 203
203
So right now, we are of course, 204
204
in the printAge scope here. 205
205
And so then JavaScript cannot find a variable 206
206
in the current scope. 207
207
So it looks up in the scope chain, 208
208
which is then the next step, 209
209
the calcAge function. 210
210
However, it can also not find first name in this scope, 211
211
and therefore it goes up even further 212
212
into the global scope. 213
213
And there it is. 214
214
And so this is the value 215
215
that is gonna be used. 216
216
Okay, so I hope 217
217
all of this made sense until this point. 218
218
Let's now go further 219
219
and also create a block scope 220
220
right here in this printAge function. 221
221
So let's do an if statement here. 222
222
And we will check if the person 223
223
based on the birth year is a millennial. 224
224
And so that is if you were born 225
225
between 1981 and 1996. 226
226
Then you're a millennial, 227
227
and so let's check for that. 228
228
So birth year needs to be 229
229
at least 1981 230
230
and below, 231
231
below 1996. 232
232
And so here we are creating a block. 233
233
And therefore, this will be a new block scope. 234
234
And so let's now 235
235
define a variable here using const. 236
236
And I'm gonna call it string. 237
237
And let's say, 238
238
so first we get this string here to the console. 239
239
And then we can also say, 240
240
so if the person is a millennial, 241
241
we will say, 242
242
oh, and you're a millennial. 243
243
And then again, the first name. 244
244
And so now we are adding 245
245
even one more step here 246
246
to the scope chain, 247
247
because now the look up for first name 248
248
is even longer. 249
249
But it still will work. 250
250
So lemme log that to the console. 251
251
And so in this case, 252
252
I am clearly a millennial, okay? 253
253
And again, Jonas here is still found 254
254
all the way here 255
255
from the outer scope. 256
256
But now, what do you think will happen 257
257
as we try to log this variable 258
258
outside of this block scope? 259
259
So basically do the same, 260
260
but outside of the block. 261
261
So indeed, we get an error that str is not defined. 262
262
And again, that's because const and let variables 263
263
are block scoped. 264
264
So they are valid. 265
265
So they are available only inside the block 266
266
in which they were created. 267
267
But now watch as we create yet another variable, 268
268
which I will call millennial. 269
269
And let's set it to true. 270
270
And so this is an old pre ES6 variable. 271
271
And so what do you think will happen, 272
272
as we log it, also here outside of this block? 273
273
So we need to comment out this one. 274
274
So again, what do you think is gonna happen now? 275
275
And JavaScript can actually find it. 276
276
And so that is because of the fact 277
277
that var variables, 278
278
so variables declared with the var keyword 279
279
are function scoped. 280
280
So they simply ignore the block, 281
281
because they are not block scoped at all. 282
282
They're just function scoped. 283
283
And so here, we are still in the same function. 284
284
So here, 285
285
here we are trying to access the variable 286
286
that was defined in the same function, right? 287
287
So right now, 288
288
the scope of the millennial variable 289
289
is this entire function, 290
290
no matter if it was declared inside of a block or not. 291
291
Because again, var variables do not care 292
292
about blocks at all. 293
293
And so therefore, 294
294
we can then access the millennial variable 295
295
inside of its scope. 296
296
Okay? 297
297
So keep that in mind as you use, 298
298
or as you see a variable declared 299
299
with var, right? 300
300
Because, as I said, 301
301
on your own, you should probably not use 302
302
this variable yourself, 303
303
always just use const, or let. 304
304
But if you are reading other code bases, 305
305
or even working with older code, 306
306
then keep in mind 307
307
that this is how the var variable works. 308
308
And so that's why it's very important 309
309
to learn about str as well. 310
310
Okay, next up, 311
311
let's prove that functions are also in fact, 312
312
block scoped starting in ES6. 313
313
So let's just create a simple 314
314
function here, that will add two values. 315
315
Return A plus B. 316
316
And then let's 317
317
attempt to call it here outside of the block. 318
318
So add two and three. 319
319
And now we get add is not defined. 320
320
And so in fact, 321
321
the scope of this add function here 322
322
is only the block in which it was defined. 323
323
So only here, 324
324
we can use the add function. 325
325
And so that proves that 326
326
functions are now in fact, block scoped. 327
327
But remember that that is only true for strict mode. 328
328
And so that's the mode 329
329
that we're actually currently in. 330
330
But if I turn this off, 331
331
you should see now actually add being called. 332
332
So let's log the result of that to the console. 333
333
And so we should now see five. 334
334
And indeed, now it works. 335
335
Now, right? 336
336
But we should always use strict mode. 337
337
And so now we should get that error back. 338
338
And so lets also comment this out. 339
339
And so you can keep this here as a reference. 340
340
Okay. 341
341
And now to finish. 342
342
Let's do some experiments here. 343
343
So what do you think is gonna happen 344
344
if we declare a variable in this scope here? 345
345
So in this new block scope that already exists 346
346
in a parent scope? 347
347
So for example, let's say here, 348
348
const 349
349
first name, equals 350
350
Steven. 351
351
So what do you think this string here 352
352
will look like now? 353
353
So do you think that here, 354
354
it will say Jonas or Steven? 355
355
Well, let's try. 356
356
And in fact, 357
357
it now says Steven, 358
358
and that happens, 359
359
because as always, 360
360
JavaScript tries to look for the variable name 361
361
in the current scope. 362
362
And right now, it actually is in the current scope. 363
363
So first name is indeed, in this same block. 364
364
So in this same scope, 365
365
and so therefore, JavaScript will then use that variable 366
366
and not perform any variable look up 367
367
in the scope chain. 368
368
So the scope chain 369
369
isn't necessary at all, 370
370
if the variable that we're looking for 371
371
is already in the current scope. 372
372
And so that's exactly the case right here. 373
373
But of course, 374
374
then outside of this block, 375
375
the first name variable 376
376
is still gonna be the one 377
377
coming from the scope chain. 378
378
So that's why here, 379
379
you still see Jonas. 380
380
So right here in the printAge function, 381
381
which is another scope. 382
382
So it's the parent scope of this scope, right? 383
383
And so here, first name is still Jonas, 384
384
because it is not in the current scope of this function. 385
385
And therefore, JavaScript will make a variable lookup 386
386
in the scope chain, 387
387
until it can find first name, 388
388
which is still Jonas, 389
389
coming from down here. 390
390
So here we created a new variable 391
391
with the same name of another variable 392
392
that we had already created in a parent scope. 393
393
So we have two first name variables right now. 394
394
But that is not a problem at all. 395
395
Because in fact, 396
396
they are completely different variables, 397
397
they simply happen to have the same name. 398
398
But that's not a problem at all, 399
399
because they are defined in different scopes. 400
400
And so you can have repeated variable names. 401
401
That's absolutely no problem. 402
402
And that's also the reason 403
403
why you can have different functions 404
404
with the same parameter names. 405
405
Because again, 406
406
each parameter is only defined in that scope 407
407
of that function. 408
408
And therefore, it's not a problem at all 409
409
to have many functions with the exact same parameter names, 410
410
in the same way that it's not a problem 411
411
to have functions with the same variable names 412
412
inside of them. 413
413
But now watch what happens when we redefine a variable 414
414
from a parent scope inside of an inner scope. 415
415
So not creating a new variable, 416
416
but simply reassigning the value 417
417
of a variable. 418
418
So let's do that here. 419
419
And let's now say 420
420
output equals 421
421
new output. 422
422
And here we then have to change 423
423
the output to a let. 424
424
But let's just analyze what we did here. 425
425
So we are in the printAge scope. 426
426
So that's all of this here. 427
427
And in here, we have the output variable, 428
428
then we have a inner scope, 429
429
so like a child scope here, 430
430
which then redefines this output variable 431
431
from the outer scope. 432
432
And so if we then try to access that output here again, 433
433
what do you think is gonna happen? 434
434
Well, we get new output here. 435
435
And that is because we actually manipulated 436
436
an existing variable here, 437
437
inside of a child scope. 438
438
So inside of an inner scope, right? 439
439
We did not create a new variable, 440
440
we simply redefined a variable that we accessed here 441
441
from the parent scope. 442
442
So if we did create a new 443
443
variable called output here, 444
444
then we would have the same situation 445
445
as before with first name. 446
446
So this would then be a completely different variable, 447
447
and would not at all affect the output from the outer scope. 448
448
And so now as we save this, 449
449
then this new output should disappear. 450
450
And should be back to the original output 451
451
as we defined it in the scope now. 452
452
So indeed, now the new output is gone. 453
453
And again, that's because 454
454
it is now its own variable. 455
455
So a brand new variable, 456
456
which just happens to have the same name 457
457
as a variable from its parent scope. 458
458
But to illustrate this here, 459
459
let's actually leave it like this. 460
460
And I will also comment it, 461
461
creating new variable with 462
462
same name as 463
463
outer scopes 464
464
variable. 465
465
And let's put this together here. 466
466
Reassigning 467
467
outer scopes 468
468
variable. 469
469
So again, two completely different things. 470
470
But I think this is a very nice example 471
471
to once again illustrate 472
472
how the scope chain works. 473
473
And with this, 474
474
I hope that you now completely understand 475
475
how scoping works in JavaScript. 476
476
Also just keep in mind 477
477
that real code should (chuckles) 478
478
probably not be this confusing, 479
479
but this was just to show you how scoping works.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.