All language subtitles for 6. Scope and The Scope Chain

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
Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated: 1 1 00:00:00,840 --> 00:00:03,090 Let's continue our journey 2 2 00:00:03,090 --> 00:00:07,330 of diving really deep into how JavaScript actually works 3 3 00:00:07,330 --> 00:00:08,960 behind the scenes. 4 4 00:00:08,960 --> 00:00:11,450 I really hope you have enjoyed it so far 5 5 00:00:11,450 --> 00:00:14,370 and are able to see the immense value 6 6 00:00:14,370 --> 00:00:17,460 that these lectures bring to the table. 7 7 00:00:17,460 --> 00:00:19,170 Now, after this lecture, 8 8 00:00:19,170 --> 00:00:22,560 there will finally be another coding lecture. 9 9 00:00:22,560 --> 00:00:25,223 So hang tight, we're almost there. 10 10 00:00:27,070 --> 00:00:30,770 But now let's get started with this lecture. 11 11 00:00:30,770 --> 00:00:33,430 So we learned in the last lecture 12 12 00:00:33,430 --> 00:00:37,810 that each execution context has a variable environment, 13 13 00:00:37,810 --> 00:00:41,340 a scope chain and a this keyword. 14 14 00:00:41,340 --> 00:00:44,510 So in this lecture, let's learn what scope 15 15 00:00:44,510 --> 00:00:46,200 and a scope chain are, 16 16 00:00:46,200 --> 00:00:49,970 why they are so important and how they work. 17 17 00:00:49,970 --> 00:00:51,930 And let's start by understanding 18 18 00:00:51,930 --> 00:00:54,190 what scoping actually means, 19 19 00:00:54,190 --> 00:00:57,930 and learn about some related concepts as well. 20 20 00:00:57,930 --> 00:01:02,250 So scoping controls how our program's variables 21 21 00:01:02,250 --> 00:01:06,293 are organized and accessed by the JavaScript engine. 22 22 00:01:07,140 --> 00:01:10,430 So basically scoping asks the question, 23 23 00:01:10,430 --> 00:01:12,560 where do variables live? 24 24 00:01:12,560 --> 00:01:16,993 Or where can we access a certain variable and where not? 25 25 00:01:18,030 --> 00:01:19,330 Now in JavaScript, 26 26 00:01:19,330 --> 00:01:22,720 we have something called lexical scoping. 27 27 00:01:22,720 --> 00:01:26,060 And lexical scoping means that the way variables 28 28 00:01:26,060 --> 00:01:28,330 are organized and accessed 29 29 00:01:28,330 --> 00:01:32,400 is entirely controlled by the placement of functions 30 30 00:01:32,400 --> 00:01:35,710 and of blocks in the programs code. 31 31 00:01:35,710 --> 00:01:39,470 For example, a function that is written inside 32 32 00:01:39,470 --> 00:01:42,940 another function has access to the variables 33 33 00:01:42,940 --> 00:01:45,930 of the parent function, okay? 34 34 00:01:45,930 --> 00:01:49,550 So again, variable scoping is influenced 35 35 00:01:49,550 --> 00:01:54,550 by where exactly we write our functions and code blocks. 36 36 00:01:55,120 --> 00:01:58,370 Okay, and now about scope itself. 37 37 00:01:58,370 --> 00:02:01,300 Scope is the space or environment 38 38 00:02:01,300 --> 00:02:04,430 in which a certain variable is declared, 39 39 00:02:04,430 --> 00:02:06,230 simple as that. 40 40 00:02:06,230 --> 00:02:08,050 And in the case of functions, 41 41 00:02:08,050 --> 00:02:10,870 that's essentially the variable environment 42 42 00:02:10,870 --> 00:02:15,020 which is stored in the functions execution context. 43 43 00:02:15,020 --> 00:02:17,210 So if now you're asking yourself, 44 44 00:02:17,210 --> 00:02:19,460 what's the difference between scope 45 45 00:02:19,460 --> 00:02:21,770 and variable environment? 46 46 00:02:21,770 --> 00:02:25,510 Then the answer is that for the case of functions, 47 47 00:02:25,510 --> 00:02:27,730 it's basically the same. 48 48 00:02:27,730 --> 00:02:30,770 Now in JavaScript, we have the global scope, 49 49 00:02:30,770 --> 00:02:33,690 function scope, and block scope. 50 50 00:02:33,690 --> 00:02:36,340 And we will talk about these in a second. 51 51 00:02:36,340 --> 00:02:39,560 But first, let's also define what the scope 52 52 00:02:39,560 --> 00:02:41,620 of a variable is. 53 53 00:02:41,620 --> 00:02:46,590 So the scope of a variable is basically the entire region 54 54 00:02:46,590 --> 00:02:51,170 of our code, where a certain variable can be accessed. 55 55 00:02:51,170 --> 00:02:55,170 Now, some people use the word scope for all of this, 56 56 00:02:55,170 --> 00:02:58,600 but I like to define all these concepts that we have here 57 57 00:02:58,600 --> 00:03:03,160 in a clear way, because actually subtle differences. 58 58 00:03:03,160 --> 00:03:06,070 For example, if you take a close look at it, 59 59 00:03:06,070 --> 00:03:09,940 scope is not the same as scope of a variable. 60 60 00:03:09,940 --> 00:03:14,430 And so you should know about the subtle differences, right? 61 61 00:03:14,430 --> 00:03:18,240 And I know it might still sound all the same for now, 62 62 00:03:18,240 --> 00:03:21,040 but after looking at a couple of examples 63 63 00:03:21,040 --> 00:03:23,050 and writing some real code, 64 64 00:03:23,050 --> 00:03:26,563 you will understand everything I just showed you here. 65 65 00:03:27,840 --> 00:03:31,000 Anyway, let's now talk about the three different types 66 66 00:03:31,000 --> 00:03:33,470 of scope in JavaScript. 67 67 00:03:33,470 --> 00:03:38,470 So that's global scope, function scope and block scope. 68 68 00:03:38,750 --> 00:03:42,030 And remember, scope is the place in our code 69 69 00:03:42,030 --> 00:03:44,940 where variables are declared. 70 70 00:03:44,940 --> 00:03:48,310 And when I say variables, the exact same thing 71 71 00:03:48,310 --> 00:03:50,800 is true for functions as well. 72 72 00:03:50,800 --> 00:03:54,420 Because in the end, functions are just values 73 73 00:03:54,420 --> 00:03:56,990 that are stored in variables. 74 74 00:03:56,990 --> 00:04:01,120 So first, the global scope is once more 75 75 00:04:01,120 --> 00:04:03,430 for top level code. 76 76 00:04:03,430 --> 00:04:06,270 So this is for variables that are declared 77 77 00:04:06,270 --> 00:04:09,930 outside of any function or block. 78 78 00:04:09,930 --> 00:04:12,840 These variables will be accessible everywhere 79 79 00:04:12,840 --> 00:04:17,050 in our program, in all functions and all blocks. 80 80 00:04:17,050 --> 00:04:19,830 So really, everywhere. 81 81 00:04:19,830 --> 00:04:23,730 Next, each and every function creates a scope. 82 82 00:04:23,730 --> 00:04:27,120 And the variables declared inside that function scope 83 83 00:04:27,120 --> 00:04:30,230 are only accessible inside that function. 84 84 00:04:30,230 --> 00:04:33,230 This is also called a local scope 85 85 00:04:33,230 --> 00:04:35,800 opposed to the global scope. 86 86 00:04:35,800 --> 00:04:40,150 So local variables live in the function so to say. 87 87 00:04:40,150 --> 00:04:41,920 And outside of the function, 88 88 00:04:41,920 --> 00:04:45,740 the variables are then not accessible at all. 89 89 00:04:45,740 --> 00:04:48,390 Again, this is technically the same 90 90 00:04:48,390 --> 00:04:51,130 as the functions variable environment, 91 91 00:04:51,130 --> 00:04:54,280 but we still need to give it the name of scope 92 92 00:04:54,280 --> 00:04:55,510 in this context, 93 93 00:04:55,510 --> 00:04:58,610 because blocks also creates scopes. 94 94 00:04:58,610 --> 00:05:01,010 Anyway, in this example here, 95 95 00:05:01,010 --> 00:05:06,010 the now variable is 2037 inside the cog H function. 96 96 00:05:06,560 --> 00:05:09,240 And therefore, we can use it in the function 97 97 00:05:09,240 --> 00:05:10,960 to do calculations. 98 98 00:05:10,960 --> 00:05:13,260 But outside of the function, 99 99 00:05:13,260 --> 00:05:15,730 as we try to log it to the console, 100 100 00:05:15,730 --> 00:05:18,440 we get a reference error. 101 101 00:05:18,440 --> 00:05:22,010 So JavaScript is trying to find the now variable 102 102 00:05:22,010 --> 00:05:23,770 in this global scope, 103 103 00:05:23,770 --> 00:05:27,370 so outside of the function, but it cannot find it. 104 104 00:05:27,370 --> 00:05:29,750 And so there is gonna be an error. 105 105 00:05:29,750 --> 00:05:32,430 And if you remember, or pick game project 106 106 00:05:32,430 --> 00:05:34,060 from the previous section, 107 107 00:05:34,060 --> 00:05:36,820 there is also the reason why we had to declare 108 108 00:05:36,820 --> 00:05:41,080 a couple of variables outside of the init function, 109 109 00:05:41,080 --> 00:05:42,410 remember that? 110 110 00:05:42,410 --> 00:05:45,920 So we had some variables declared in the init function, 111 111 00:05:45,920 --> 00:05:47,570 and then that gave us an error 112 112 00:05:47,570 --> 00:05:50,030 because other functions were trying 113 113 00:05:50,030 --> 00:05:51,860 to access these variables. 114 114 00:05:51,860 --> 00:05:54,580 But of course they were in the function scope. 115 115 00:05:54,580 --> 00:05:56,860 And so they were locally scoped, 116 116 00:05:56,860 --> 00:05:58,210 and so we couldn't access them 117 117 00:05:58,210 --> 00:06:02,400 outside of that function where they were declared. 118 118 00:06:02,400 --> 00:06:04,610 And here, it actually does not matter 119 119 00:06:04,610 --> 00:06:07,230 what kind of function we're using. 120 120 00:06:07,230 --> 00:06:10,380 So function declarations, function expressions 121 121 00:06:10,380 --> 00:06:14,223 and arrow functions all create their own scope. 122 122 00:06:15,260 --> 00:06:19,500 Now traditionally, only functions used to create scopes 123 123 00:06:19,500 --> 00:06:20,850 in JavaScript. 124 124 00:06:20,850 --> 00:06:25,850 But starting in ES6, blocks also creates scopes now. 125 125 00:06:25,860 --> 00:06:26,810 And with blocks, 126 126 00:06:26,810 --> 00:06:29,970 we mean everything that is between curly braces, 127 127 00:06:29,970 --> 00:06:34,510 such as the block of an if statement or a for loop. 128 128 00:06:34,510 --> 00:06:36,920 So just like with functions, 129 129 00:06:36,920 --> 00:06:39,570 variables declared inside a block 130 130 00:06:39,570 --> 00:06:42,350 are only accessible inside that block 131 131 00:06:42,350 --> 00:06:44,970 and not outside of it. 132 132 00:06:44,970 --> 00:06:47,950 Now, the big difference is that block scopes 133 133 00:06:47,950 --> 00:06:52,950 only apply to variables declared with let or const, okay? 134 134 00:06:53,540 --> 00:06:57,500 So again, only let and const variables 135 135 00:06:57,500 --> 00:07:01,600 are restricted to the block in which they were created. 136 136 00:07:01,600 --> 00:07:04,910 That's why we say that let and const variables 137 137 00:07:04,910 --> 00:07:06,710 are block scoped. 138 138 00:07:06,710 --> 00:07:10,890 So if I declared a variable using var in this block, 139 139 00:07:10,890 --> 00:07:14,520 then that variable would actually still be accessible 140 140 00:07:14,520 --> 00:07:16,550 outside of the block, 141 141 00:07:16,550 --> 00:07:19,430 and would be scoped to the current function 142 142 00:07:19,430 --> 00:07:21,410 or to the global scope. 143 143 00:07:21,410 --> 00:07:25,570 And so we say that var is function scoped. 144 144 00:07:25,570 --> 00:07:27,970 So in ES5 and before, 145 145 00:07:27,970 --> 00:07:31,260 we only had global scope and function scope. 146 146 00:07:31,260 --> 00:07:35,400 And that's why ES5 variables declared with var, 147 147 00:07:35,400 --> 00:07:39,080 only care about functions, but not about blocks. 148 148 00:07:39,080 --> 00:07:40,960 They simply ignore them. 149 149 00:07:40,960 --> 00:07:44,170 Finally, also starting in ES6, 150 150 00:07:44,170 --> 00:07:47,070 all functions are now also block scoped, 151 151 00:07:47,070 --> 00:07:49,010 at least in strict mode, 152 152 00:07:49,010 --> 00:07:52,040 which you should always be using anyway. 153 153 00:07:52,040 --> 00:07:55,420 And just like with let and const variables, 154 154 00:07:55,420 --> 00:07:58,750 this means that functions declared inside a block 155 155 00:07:58,750 --> 00:08:03,410 are only accessible inside that block, okay? 156 156 00:08:03,410 --> 00:08:06,730 And we will see examples of all that in the next video, 157 157 00:08:06,730 --> 00:08:09,023 when we're gonna go back to coding. 158 158 00:08:10,230 --> 00:08:13,930 So to recap, let and const variables 159 159 00:08:13,930 --> 00:08:17,260 as well as functions are block scoped. 160 160 00:08:17,260 --> 00:08:20,440 And if you already know other programming languages, 161 161 00:08:20,440 --> 00:08:23,090 block scoping is probably more in line 162 162 00:08:23,090 --> 00:08:25,230 with what you already know. 163 163 00:08:25,230 --> 00:08:28,680 Function scopes are weird for some beginners 164 164 00:08:28,680 --> 00:08:30,400 in the JavaScript world. 165 165 00:08:30,400 --> 00:08:35,070 And that's why block scopes were introduced in ES6. 166 166 00:08:35,070 --> 00:08:38,440 But now to understand all this a little bit better, 167 167 00:08:38,440 --> 00:08:42,560 let's actually look at a more real and detailed example 168 168 00:08:42,560 --> 00:08:45,493 and also learn about the scope chain. 169 169 00:08:47,520 --> 00:08:50,520 And here we have some code with different functions 170 170 00:08:50,520 --> 00:08:51,650 and blocks, 171 171 00:08:51,650 --> 00:08:53,720 and we're gonna take a look at the scopes 172 172 00:08:53,720 --> 00:08:58,330 that are in this code as well as build the scope chain. 173 173 00:08:58,330 --> 00:09:02,290 And of course, we start with the global scope. 174 174 00:09:02,290 --> 00:09:05,030 As you can see, the myName variable 175 175 00:09:05,030 --> 00:09:07,360 is the only variable declaration 176 176 00:09:07,360 --> 00:09:10,100 that we have in the global scope. 177 177 00:09:10,100 --> 00:09:12,600 Now, technically, the first function 178 178 00:09:12,600 --> 00:09:14,700 also counts as a variable 179 179 00:09:14,700 --> 00:09:17,010 that is present in the global scope, 180 180 00:09:17,010 --> 00:09:18,870 but I want to keep it simple here. 181 181 00:09:18,870 --> 00:09:22,180 And so I will only consider variable declarations 182 182 00:09:22,180 --> 00:09:24,510 and no functions, all right? 183 183 00:09:24,510 --> 00:09:27,500 Just keep in mind that whatever I'm explaining here 184 184 00:09:27,500 --> 00:09:31,363 for variables also works the same for functions. 185 185 00:09:32,310 --> 00:09:35,020 Anyway, inside the global scope, 186 186 00:09:35,020 --> 00:09:38,220 we have a scope for the first function 187 187 00:09:38,220 --> 00:09:42,820 because each function creates its own scope, remember? 188 188 00:09:42,820 --> 00:09:44,970 And what's in the scope? 189 189 00:09:44,970 --> 00:09:47,870 Well, it's to age variable that's declared 190 190 00:09:47,870 --> 00:09:50,500 right at the top of the function. 191 191 00:09:50,500 --> 00:09:52,960 Next inside the first scope, 192 192 00:09:52,960 --> 00:09:55,670 let's now consider the second function, 193 193 00:09:55,670 --> 00:09:58,270 which will also create its own scope 194 194 00:09:58,270 --> 00:10:01,820 containing the job variable set to teacher. 195 195 00:10:01,820 --> 00:10:03,060 So as you see, 196 196 00:10:03,060 --> 00:10:06,400 we have a nested structure of scopes 197 197 00:10:06,400 --> 00:10:09,490 with one scope inside the other. 198 198 00:10:09,490 --> 00:10:12,680 But now comes the actually interesting part. 199 199 00:10:12,680 --> 00:10:15,200 Because here in the second function, 200 200 00:10:15,200 --> 00:10:17,180 we have this line of code 201 201 00:10:17,180 --> 00:10:19,810 where we need the myName variable 202 202 00:10:19,810 --> 00:10:21,610 and the age variable, 203 203 00:10:21,610 --> 00:10:26,070 which were both not declared inside the current scope. 204 204 00:10:26,070 --> 00:10:28,720 But we really need these variables here, 205 205 00:10:28,720 --> 00:10:33,530 because otherwise we can't create this string here, right? 206 206 00:10:33,530 --> 00:10:35,700 So how can this be fixed? 207 207 00:10:35,700 --> 00:10:38,890 How will the JavaScript engine know the values 208 208 00:10:38,890 --> 00:10:40,970 of these variables? 209 209 00:10:40,970 --> 00:10:43,730 Well, the secret is that every scope 210 210 00:10:43,730 --> 00:10:46,520 always has access to all the variables 211 211 00:10:46,520 --> 00:10:49,050 from all its outer scopes. 212 212 00:10:49,050 --> 00:10:51,710 So from all its parent scopes. 213 213 00:10:51,710 --> 00:10:54,970 In our example, this means that the second scope 214 214 00:10:54,970 --> 00:10:57,950 can access the age variable from the scope 215 215 00:10:57,950 --> 00:10:59,900 of the first function. 216 216 00:10:59,900 --> 00:11:03,010 Of course, this also means that the first scope 217 217 00:11:03,010 --> 00:11:06,690 can access variables that are in the global scope, 218 218 00:11:06,690 --> 00:11:09,560 because that is the parent scope. 219 219 00:11:09,560 --> 00:11:11,480 As a consequence of this, 220 220 00:11:11,480 --> 00:11:14,870 the second scope will then also be able to access 221 221 00:11:14,870 --> 00:11:18,140 the myName variable from the global scope, 222 222 00:11:18,140 --> 00:11:21,030 because it has access to the variables 223 223 00:11:21,030 --> 00:11:22,713 from the first scope. 224 224 00:11:23,670 --> 00:11:28,180 And by the way, all this also applies to function arguments. 225 225 00:11:28,180 --> 00:11:31,043 But in this example, we just don't have any. 226 226 00:11:31,900 --> 00:11:36,590 And this is essentially how the scope chain works. 227 227 00:11:36,590 --> 00:11:37,650 In other words, 228 228 00:11:37,650 --> 00:11:41,130 if one scope needs to use a certain variable, 229 229 00:11:41,130 --> 00:11:43,940 but cannot find it in the current scope, 230 230 00:11:43,940 --> 00:11:46,460 it will look up in the scope chain 231 231 00:11:46,460 --> 00:11:48,840 and see if it can find a variable 232 232 00:11:48,840 --> 00:11:51,060 in one of the parent scopes. 233 233 00:11:51,060 --> 00:11:54,160 If it can, it will then use that variable. 234 234 00:11:54,160 --> 00:11:57,620 And if it can't, then there will be an error. 235 235 00:11:57,620 --> 00:12:00,503 And this process is called variable lookup. 236 236 00:12:01,870 --> 00:12:04,710 Now it's important to note that these variables 237 237 00:12:04,710 --> 00:12:09,460 are not copied from one scope to another, okay? 238 238 00:12:09,460 --> 00:12:13,190 Instead, scopes simply look up in the scope chain 239 239 00:12:13,190 --> 00:12:15,970 until they find a variable that they need 240 240 00:12:15,970 --> 00:12:17,940 and then they use it. 241 241 00:12:17,940 --> 00:12:20,760 What's also extremely important to note 242 242 00:12:20,760 --> 00:12:24,240 is that this does not work the other way around. 243 243 00:12:24,240 --> 00:12:27,560 A certain scope will never, ever have access 244 244 00:12:27,560 --> 00:12:29,940 to the variables of an inner scope. 245 245 00:12:29,940 --> 00:12:33,650 In this example, the first scope, for example, 246 246 00:12:33,650 --> 00:12:36,900 will never get access to the job variable 247 247 00:12:36,900 --> 00:12:40,840 that is stored in the second scope, okay? 248 248 00:12:40,840 --> 00:12:45,460 So again, one scope can only look up in a scope chain, 249 249 00:12:45,460 --> 00:12:48,520 but it cannot look down basically. 250 250 00:12:48,520 --> 00:12:50,840 So only parent scope can be used, 251 251 00:12:50,840 --> 00:12:52,603 but no child scopes. 252 252 00:12:53,450 --> 00:12:56,220 Anyway, with all this in place now, 253 253 00:12:56,220 --> 00:12:58,690 this line of code can be executed 254 254 00:12:58,690 --> 00:13:00,400 and print to the console. 255 255 00:13:00,400 --> 00:13:03,390 Jonas is a 30 year old teacher, 256 256 00:13:03,390 --> 00:13:06,460 even though the myName and age variables 257 257 00:13:06,460 --> 00:13:09,260 were not defined in the current scope. 258 258 00:13:09,260 --> 00:13:13,950 All the engine did was to get them from the scope chain. 259 259 00:13:13,950 --> 00:13:16,140 And as you might be noticing, 260 260 00:13:16,140 --> 00:13:20,180 we have actually already done this before in our own code. 261 261 00:13:20,180 --> 00:13:23,520 We just didn't really understand what was going on 262 262 00:13:23,520 --> 00:13:25,300 and how it all worked. 263 263 00:13:25,300 --> 00:13:27,940 But now we do know how it works. 264 264 00:13:27,940 --> 00:13:29,233 Amazing, right? 265 265 00:13:30,180 --> 00:13:33,870 Anyway, we still have one more scope left here, 266 266 00:13:33,870 --> 00:13:36,993 and that's the one created by this block here. 267 267 00:13:38,010 --> 00:13:40,880 Remember that starting with ES6, 268 268 00:13:40,880 --> 00:13:45,130 not only functions create scopes, but also blocks. 269 269 00:13:45,130 --> 00:13:49,810 However, these scopes only work for the ES6 variable types. 270 270 00:13:49,810 --> 00:13:52,930 So for let and const variables. 271 271 00:13:52,930 --> 00:13:56,010 That's why the only variable that's in the scope 272 272 00:13:56,010 --> 00:13:58,480 is the decade variable. 273 273 00:13:58,480 --> 00:14:02,650 The millennial variable isn't declared with const or let, 274 274 00:14:02,650 --> 00:14:07,380 and therefore it is not scoped to just this block. 275 275 00:14:07,380 --> 00:14:11,270 Instead, the millennial variable is actually part 276 276 00:14:11,270 --> 00:14:13,580 of the first function scope. 277 277 00:14:13,580 --> 00:14:17,780 So again, for a variable declared with var, 278 278 00:14:17,780 --> 00:14:20,490 block scopes don't apply at all. 279 279 00:14:20,490 --> 00:14:24,160 They are functions scoped, not block scoped. 280 280 00:14:24,160 --> 00:14:26,700 Let and const on the other hand 281 281 00:14:26,700 --> 00:14:30,440 are in fact blocks scoped, okay? 282 282 00:14:30,440 --> 00:14:32,690 This is one of the fundamental things 283 283 00:14:32,690 --> 00:14:36,710 that you need to keep in mind about let, const and var, 284 284 00:14:36,710 --> 00:14:39,760 and about scoping in general. 285 285 00:14:39,760 --> 00:14:43,280 So if you're taking notes and I hope you are taking 286 286 00:14:43,280 --> 00:14:44,970 lots of notes, 287 287 00:14:44,970 --> 00:14:47,543 then this must definitely be in there. 288 288 00:14:48,450 --> 00:14:50,330 Now about a scope chain, 289 289 00:14:50,330 --> 00:14:54,043 if the millennial variable is in the first function scope, 290 290 00:14:54,043 --> 00:14:57,010 then of course the second function scope 291 291 00:14:57,010 --> 00:14:59,130 also has access to it, 292 292 00:14:59,130 --> 00:15:02,550 even if it doesn't really need that variable. 293 293 00:15:02,550 --> 00:15:04,810 Also the scope chain does of course, 294 294 00:15:04,810 --> 00:15:07,500 apply to block scopes as well. 295 295 00:15:07,500 --> 00:15:10,400 And therefore in or if block scope, 296 296 00:15:10,400 --> 00:15:13,120 we get access to all the variables 297 297 00:15:13,120 --> 00:15:15,670 from all its outer scopes. 298 298 00:15:15,670 --> 00:15:17,950 So from the first function scope, 299 299 00:15:17,950 --> 00:15:20,890 and of course from the global scope. 300 300 00:15:20,890 --> 00:15:23,090 That's why I said in the last slide 301 301 00:15:23,090 --> 00:15:25,110 that variables in a global scope 302 302 00:15:25,110 --> 00:15:27,640 are accessible from everywhere. 303 303 00:15:27,640 --> 00:15:29,760 They are, because they are always 304 304 00:15:29,760 --> 00:15:32,290 at the top of the scope chain. 305 305 00:15:32,290 --> 00:15:35,350 In fact, we call variables in the global scope, 306 306 00:15:35,350 --> 00:15:39,200 global variables, very creative, right? 307 307 00:15:39,200 --> 00:15:43,670 But we actually use this term a lot in JavaScript. 308 308 00:15:43,670 --> 00:15:45,630 Now it's important to understand 309 309 00:15:45,630 --> 00:15:47,890 that our purple blocks scope 310 310 00:15:47,890 --> 00:15:50,920 does not get access to any variables 311 311 00:15:50,920 --> 00:15:53,890 from the yellow second function scope. 312 312 00:15:53,890 --> 00:15:56,240 And the same, the other way around. 313 313 00:15:56,240 --> 00:15:58,070 And why is that? 314 314 00:15:58,070 --> 00:16:00,920 Well it's because of lexical scoping 315 315 00:16:00,920 --> 00:16:03,230 as we learned in the last slide. 316 316 00:16:03,230 --> 00:16:05,710 So the way that we can access variables 317 317 00:16:05,710 --> 00:16:08,660 depends on where the scope is placed, 318 318 00:16:08,660 --> 00:16:11,650 so where it is written in the code. 319 319 00:16:11,650 --> 00:16:14,730 In this case, none of these two scopes is written 320 320 00:16:14,730 --> 00:16:17,110 inside of one another. 321 321 00:16:17,110 --> 00:16:20,810 They're both child scopes of the first function. 322 322 00:16:20,810 --> 00:16:24,400 We could even say that they are a sibling scopes. 323 323 00:16:24,400 --> 00:16:27,250 And so by the rules of lexical scoping, 324 324 00:16:27,250 --> 00:16:31,070 they cannot have access to each others variables, 325 325 00:16:31,070 --> 00:16:35,530 simply because one is not written inside the other one. 326 326 00:16:35,530 --> 00:16:37,540 We can also say that the scope chain 327 327 00:16:37,540 --> 00:16:40,803 only works upwards, not sideways. 328 328 00:16:41,860 --> 00:16:45,200 Okay, so this was a lot to take in, 329 329 00:16:45,200 --> 00:16:48,430 but I hope that everything's still keeps making sense 330 330 00:16:48,430 --> 00:16:49,670 at this point. 331 331 00:16:49,670 --> 00:16:51,400 And if not, don't worry, 332 332 00:16:51,400 --> 00:16:54,010 we will see all this working in practice 333 333 00:16:54,010 --> 00:16:56,060 in the next video. 334 334 00:16:56,060 --> 00:16:57,380 But for now, though, 335 335 00:16:57,380 --> 00:17:00,350 there is one more thing that we need to talk about, 336 336 00:17:00,350 --> 00:17:03,010 which is the difference between the scope chain 337 337 00:17:03,010 --> 00:17:04,740 and to call stack. 338 338 00:17:04,740 --> 00:17:08,360 I get a lot of questions about this all the time. 339 339 00:17:08,360 --> 00:17:10,840 And so I decided to talk about 340 340 00:17:10,840 --> 00:17:13,900 how the call stack, execution context, 341 341 00:17:13,900 --> 00:17:16,360 variable environments and scope 342 342 00:17:16,360 --> 00:17:19,310 are all related to one another. 343 343 00:17:19,310 --> 00:17:22,470 So before we move on to the next video. 344 344 00:17:22,470 --> 00:17:23,303 And once more, 345 345 00:17:23,303 --> 00:17:25,703 let's look at some more code here. 346 346 00:17:26,720 --> 00:17:31,550 So we have three functions called first, second and third, 347 347 00:17:31,550 --> 00:17:34,760 in order to make this easier to understand. 348 348 00:17:34,760 --> 00:17:37,430 We start by calling the first function, 349 349 00:17:37,430 --> 00:17:39,730 which then calls the second function, 350 350 00:17:39,730 --> 00:17:42,950 which in turn calls the third function. 351 351 00:17:42,950 --> 00:17:45,130 So from what we learned before, 352 352 00:17:45,130 --> 00:17:50,130 the call stack for this example will look like this, right? 353 353 00:17:50,780 --> 00:17:53,870 One execution context for each function 354 354 00:17:53,870 --> 00:17:57,250 in the exact order in which they were called. 355 355 00:17:57,250 --> 00:17:59,910 They also included the variable environment 356 356 00:17:59,910 --> 00:18:02,570 of each execution context. 357 357 00:18:02,570 --> 00:18:06,010 For now, all this has nothing to do with scopes 358 358 00:18:06,010 --> 00:18:08,490 or the scope chain, all right? 359 359 00:18:08,490 --> 00:18:12,000 All I'm doing is creating one execution context 360 360 00:18:12,000 --> 00:18:14,560 for each function call and filling it 361 361 00:18:14,560 --> 00:18:17,820 with the variables of that function. 362 362 00:18:17,820 --> 00:18:20,410 And you can pause the video here for a moment 363 363 00:18:20,410 --> 00:18:24,003 to understand the content of each variable environment. 364 364 00:18:25,440 --> 00:18:28,120 Okay, and now that you did that 365 365 00:18:28,120 --> 00:18:31,770 and we have all these variable environments in place, 366 366 00:18:31,770 --> 00:18:35,250 we can actually start building the scope chain. 367 367 00:18:35,250 --> 00:18:39,300 As always, we're gonna start with the global scope. 368 368 00:18:39,300 --> 00:18:42,390 And the variables available in the global scope 369 369 00:18:42,390 --> 00:18:46,360 are exactly the ones stored in the variable environment 370 370 00:18:46,360 --> 00:18:49,160 of the global execution context. 371 371 00:18:49,160 --> 00:18:52,020 And given everything we've learned so far, 372 372 00:18:52,020 --> 00:18:54,670 that makes sense, right? 373 373 00:18:54,670 --> 00:18:56,800 And note that in this example, 374 374 00:18:56,800 --> 00:19:00,640 I am actually including functions in each scope 375 375 00:19:00,640 --> 00:19:03,283 unlike we did in the previous slide. 376 376 00:19:04,150 --> 00:19:08,110 Now in the global scope, we also call the first function, 377 377 00:19:08,110 --> 00:19:11,880 which is the reason why we have an execution context for it 378 378 00:19:11,880 --> 00:19:13,530 in the call stack. 379 379 00:19:13,530 --> 00:19:17,260 And this function of course, also gets its own scope, 380 380 00:19:17,260 --> 00:19:20,140 which contains all the variables that are declared 381 381 00:19:20,140 --> 00:19:22,620 inside of the function. 382 382 00:19:22,620 --> 00:19:26,100 And once again, this is exactly the same 383 383 00:19:26,100 --> 00:19:27,900 as the variable environment 384 384 00:19:27,900 --> 00:19:30,820 of the functions execution context. 385 385 00:19:30,820 --> 00:19:32,930 However, that's not all 386 386 00:19:32,930 --> 00:19:36,550 because now we already know about the scope chain. 387 387 00:19:36,550 --> 00:19:40,740 So the first scope also gets access to all the variables 388 388 00:19:40,740 --> 00:19:42,440 from its parent scope, 389 389 00:19:42,440 --> 00:19:44,353 thanks to the scope chain. 390 390 00:19:45,220 --> 00:19:46,860 Now, as we already know, 391 391 00:19:46,860 --> 00:19:49,530 the scope chain is all about the order 392 392 00:19:49,530 --> 00:19:53,080 in which functions are written in the code. 393 393 00:19:53,080 --> 00:19:55,450 But what's really important to note here 394 394 00:19:55,450 --> 00:19:59,400 is that the scope chain has nothing to do with the order 395 395 00:19:59,400 --> 00:20:01,370 in which functions were called. 396 396 00:20:01,370 --> 00:20:05,180 Or in other words, the scope chain has nothing to do 397 397 00:20:05,180 --> 00:20:10,180 with the order of the execution contexts in the call stack. 398 398 00:20:10,280 --> 00:20:13,590 The scope chain does get the variable environments 399 399 00:20:13,590 --> 00:20:17,960 from the execution context as shown by the red arrows here, 400 400 00:20:17,960 --> 00:20:19,520 but that's it. 401 401 00:20:19,520 --> 00:20:22,870 The order of function calls is not relevant 402 402 00:20:22,870 --> 00:20:26,120 to the scope chain at all, all right? 403 403 00:20:26,120 --> 00:20:28,550 Really keep that in mind. 404 404 00:20:28,550 --> 00:20:32,000 Now, moving on to the second function now, 405 405 00:20:32,000 --> 00:20:37,000 once again, its scope is equal to its variable environment. 406 406 00:20:37,280 --> 00:20:41,650 Also it's lexically written within the first function. 407 407 00:20:41,650 --> 00:20:43,000 And so of course, 408 408 00:20:43,000 --> 00:20:47,120 it will have access to all its parent scopes as well. 409 409 00:20:47,120 --> 00:20:50,570 So we can say that the scope chain in a certain scope 410 410 00:20:50,570 --> 00:20:54,640 is equal to adding together all the variable environments 411 411 00:20:54,640 --> 00:20:57,000 of all the parent scopes. 412 412 00:20:57,000 --> 00:20:58,790 And so this is our scope, 413 413 00:20:58,790 --> 00:21:02,230 and the scope chain are built in the JavaScript engine 414 414 00:21:02,230 --> 00:21:03,663 behind the scenes. 415 415 00:21:04,650 --> 00:21:05,650 Okay. 416 416 00:21:05,650 --> 00:21:07,700 Now in the second function, 417 417 00:21:07,700 --> 00:21:11,220 we try to call the third function. 418 418 00:21:11,220 --> 00:21:13,270 But why does that work? 419 419 00:21:13,270 --> 00:21:16,150 Well, it works because the third function 420 420 00:21:16,150 --> 00:21:20,010 is in the scope chain of the second function scope 421 421 00:21:20,010 --> 00:21:23,770 as we can see here in our scope chain diagram. 422 422 00:21:23,770 --> 00:21:28,470 It's a function in the global scope or a global function, 423 423 00:21:28,470 --> 00:21:32,030 and therefore it's accessible everywhere. 424 424 00:21:32,030 --> 00:21:34,740 Of course, this will create a new scope 425 425 00:21:34,740 --> 00:21:38,363 along with the scope chain as we already know. 426 426 00:21:39,230 --> 00:21:43,330 Great, so what happens in this third function? 427 427 00:21:43,330 --> 00:21:47,120 Well, we're trying to act as variables B, C, 428 428 00:21:47,120 --> 00:21:49,750 D and A here. 429 429 00:21:49,750 --> 00:21:53,160 D is no problem because it's right there 430 430 00:21:53,160 --> 00:21:55,330 in the third function scope. 431 431 00:21:55,330 --> 00:21:57,610 So that one is easy. 432 432 00:21:57,610 --> 00:22:01,460 Then variable C is not in a local scope 433 433 00:22:01,460 --> 00:22:05,460 and so JavaScript needs to do a variable lookup. 434 434 00:22:05,460 --> 00:22:07,810 So it looks up in a scope chain 435 435 00:22:07,810 --> 00:22:10,120 looking for variable C, 436 436 00:22:10,120 --> 00:22:12,300 but it's not there. 437 437 00:22:12,300 --> 00:22:14,010 And of course it isn't, 438 438 00:22:14,010 --> 00:22:17,510 because C is defined in the second function, 439 439 00:22:17,510 --> 00:22:20,980 and there is just no way in which the third function 440 440 00:22:20,980 --> 00:22:25,420 can access variables defined in the second function. 441 441 00:22:25,420 --> 00:22:26,540 And that is true, 442 442 00:22:26,540 --> 00:22:30,640 even though it was the second function who called the third. 443 443 00:22:30,640 --> 00:22:32,780 And so here is even more proof 444 444 00:22:32,780 --> 00:22:35,400 that the order in which functions are called 445 445 00:22:35,400 --> 00:22:38,840 does not affect the scope chain at all. 446 446 00:22:38,840 --> 00:22:40,970 And so here as a result, 447 447 00:22:40,970 --> 00:22:42,990 we get the reference error 448 448 00:22:42,990 --> 00:22:46,700 because both C and B cannot be found 449 449 00:22:46,700 --> 00:22:50,063 in the third scope nor in the scope chain. 450 450 00:22:51,030 --> 00:22:51,863 Okay. 451 451 00:22:51,863 --> 00:22:54,810 And with this, I hope I made it crystal clear 452 452 00:22:54,810 --> 00:22:58,540 that execution context, variable environments, 453 453 00:22:58,540 --> 00:23:03,240 the call stack scope and the scope chain are all different, 454 454 00:23:03,240 --> 00:23:06,040 but still very related concepts. 455 455 00:23:06,040 --> 00:23:08,450 And if it's not yet crystal clear, 456 456 00:23:08,450 --> 00:23:12,220 then it's no problem to maybe rewatch this slide, 457 457 00:23:12,220 --> 00:23:15,423 or maybe even this entire lecture a little bit later. 458 458 00:23:16,540 --> 00:23:19,830 And I know that this was quite a long lecture 459 459 00:23:19,830 --> 00:23:23,000 with a ton of stuff to take in. 460 460 00:23:23,000 --> 00:23:25,250 And so here is a handy summary 461 461 00:23:25,250 --> 00:23:28,830 with the main takeaways from this video. 462 462 00:23:28,830 --> 00:23:32,667 So to start, scoping asks the question, 463 463 00:23:32,667 --> 00:23:34,990 "Where do variables live?" 464 464 00:23:34,990 --> 00:23:38,277 Or "Where can we access a certain variable, 465 465 00:23:38,277 --> 00:23:39,860 "and where not?" 466 466 00:23:39,860 --> 00:23:42,623 That's what scoping is all about. 467 467 00:23:43,480 --> 00:23:47,230 Now, there are three types scope in JavaScript. 468 468 00:23:47,230 --> 00:23:50,810 The global scope, scopes defined by functions 469 469 00:23:50,810 --> 00:23:55,570 and scopes defined by blocks, starting in ES6. 470 470 00:23:55,570 --> 00:24:00,200 However, only let and const variables are block scoped. 471 471 00:24:00,200 --> 00:24:04,030 Variables declared with var automatically end up 472 472 00:24:04,030 --> 00:24:05,993 in the closest function scope. 473 473 00:24:06,830 --> 00:24:10,590 Next in JavaScript, we have lexical scoping, 474 474 00:24:10,590 --> 00:24:14,580 which means that the rules of where we can access variables 475 475 00:24:14,580 --> 00:24:17,100 are based on where in the code functions 476 476 00:24:17,100 --> 00:24:18,943 and blocks are written. 477 477 00:24:19,820 --> 00:24:22,580 And now, let the magic begin, 478 478 00:24:22,580 --> 00:24:25,820 because every scope always has access 479 479 00:24:25,820 --> 00:24:29,710 to all the variables from all it's outer scopes. 480 480 00:24:29,710 --> 00:24:32,890 And this is what we call the scope chain. 481 481 00:24:32,890 --> 00:24:36,630 When a certain variable is not in the current scope, 482 482 00:24:36,630 --> 00:24:39,150 the engine looks up in the scope chain 483 483 00:24:39,150 --> 00:24:42,630 until it finds the variable that it's looking for, 484 484 00:24:42,630 --> 00:24:46,240 and this process is called variable lookup. 485 485 00:24:46,240 --> 00:24:48,720 It's important to note that the scope chain 486 486 00:24:48,720 --> 00:24:50,850 is a one way street. 487 487 00:24:50,850 --> 00:24:55,300 So a scope will never ever have access to the variables 488 488 00:24:55,300 --> 00:24:59,620 of an inner scope, only of outer scopes. 489 489 00:24:59,620 --> 00:25:03,490 We can also think of the scope chain in a certain scope 490 490 00:25:03,490 --> 00:25:05,690 as being equal to adding together 491 491 00:25:05,690 --> 00:25:10,280 all the variable environments of all the parent scopes. 492 492 00:25:10,280 --> 00:25:12,780 And finally, we need to keep in mind 493 493 00:25:12,780 --> 00:25:15,350 that the scope chain has nothing to do 494 494 00:25:15,350 --> 00:25:18,970 with the order in which functions were called. 495 495 00:25:18,970 --> 00:25:21,460 So the order of function calls 496 496 00:25:21,460 --> 00:25:24,343 does not affect the scope chain at all. 497 497 00:25:25,260 --> 00:25:27,920 Okay, and now that's actually it. 498 498 00:25:27,920 --> 00:25:32,410 This is in a nutshell, scoping in JavaScript. 499 499 00:25:32,410 --> 00:25:34,363 See you in the next video. 43378

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