All language subtitles for 6. Scope and The Scope Chain

af Afrikaans
ak Akan
sq Albanian
am Amharic
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
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

Let's continue our journey 2

2

of diving really deep into how JavaScript actually works 3

3

behind the scenes. 4

4

I really hope you have enjoyed it so far 5

5

and are able to see the immense value 6

6

that these lectures bring to the table. 7

7

Now, after this lecture, 8

8

there will finally be another coding lecture. 9

9

So hang tight, we're almost there. 10

10

But now let's get started with this lecture. 11

11

So we learned in the last lecture 12

12

that each execution context has a variable environment, 13

13

a scope chain and a this keyword. 14

14

So in this lecture, let's learn what scope 15

15

and a scope chain are, 16

16

why they are so important and how they work. 17

17

And let's start by understanding 18

18

what scoping actually means, 19

19

and learn about some related concepts as well. 20

20

So scoping controls how our program's variables 21

21

are organized and accessed by the JavaScript engine. 22

22

So basically scoping asks the question, 23

23

where do variables live? 24

24

Or where can we access a certain variable and where not? 25

25

Now in JavaScript, 26

26

we have something called lexical scoping. 27

27

And lexical scoping means that the way variables 28

28

are organized and accessed 29

29

is entirely controlled by the placement of functions 30

30

and of blocks in the programs code. 31

31

For example, a function that is written inside 32

32

another function has access to the variables 33

33

of the parent function, okay? 34

34

So again, variable scoping is influenced 35

35

by where exactly we write our functions and code blocks. 36

36

Okay, and now about scope itself. 37

37

Scope is the space or environment 38

38

in which a certain variable is declared, 39

39

simple as that. 40

40

And in the case of functions, 41

41

that's essentially the variable environment 42

42

which is stored in the functions execution context. 43

43

So if now you're asking yourself, 44

44

what's the difference between scope 45

45

and variable environment? 46

46

Then the answer is that for the case of functions, 47

47

it's basically the same. 48

48

Now in JavaScript, we have the global scope, 49

49

function scope, and block scope. 50

50

And we will talk about these in a second. 51

51

But first, let's also define what the scope 52

52

of a variable is. 53

53

So the scope of a variable is basically the entire region 54

54

of our code, where a certain variable can be accessed. 55

55

Now, some people use the word scope for all of this, 56

56

but I like to define all these concepts that we have here 57

57

in a clear way, because actually subtle differences. 58

58

For example, if you take a close look at it, 59

59

scope is not the same as scope of a variable. 60

60

And so you should know about the subtle differences, right? 61

61

And I know it might still sound all the same for now, 62

62

but after looking at a couple of examples 63

63

and writing some real code, 64

64

you will understand everything I just showed you here. 65

65

Anyway, let's now talk about the three different types 66

66

of scope in JavaScript. 67

67

So that's global scope, function scope and block scope. 68

68

And remember, scope is the place in our code 69

69

where variables are declared. 70

70

And when I say variables, the exact same thing 71

71

is true for functions as well. 72

72

Because in the end, functions are just values 73

73

that are stored in variables. 74

74

So first, the global scope is once more 75

75

for top level code. 76

76

So this is for variables that are declared 77

77

outside of any function or block. 78

78

These variables will be accessible everywhere 79

79

in our program, in all functions and all blocks. 80

80

So really, everywhere. 81

81

Next, each and every function creates a scope. 82

82

And the variables declared inside that function scope 83

83

are only accessible inside that function. 84

84

This is also called a local scope 85

85

opposed to the global scope. 86

86

So local variables live in the function so to say. 87

87

And outside of the function, 88

88

the variables are then not accessible at all. 89

89

Again, this is technically the same 90

90

as the functions variable environment, 91

91

but we still need to give it the name of scope 92

92

in this context, 93

93

because blocks also creates scopes. 94

94

Anyway, in this example here, 95

95

the now variable is 2037 inside the cog H function. 96

96

And therefore, we can use it in the function 97

97

to do calculations. 98

98

But outside of the function, 99

99

as we try to log it to the console, 100

100

we get a reference error. 101

101

So JavaScript is trying to find the now variable 102

102

in this global scope, 103

103

so outside of the function, but it cannot find it. 104

104

And so there is gonna be an error. 105

105

And if you remember, or pick game project 106

106

from the previous section, 107

107

there is also the reason why we had to declare 108

108

a couple of variables outside of the init function, 109

109

remember that? 110

110

So we had some variables declared in the init function, 111

111

and then that gave us an error 112

112

because other functions were trying 113

113

to access these variables. 114

114

But of course they were in the function scope. 115

115

And so they were locally scoped, 116

116

and so we couldn't access them 117

117

outside of that function where they were declared. 118

118

And here, it actually does not matter 119

119

what kind of function we're using. 120

120

So function declarations, function expressions 121

121

and arrow functions all create their own scope. 122

122

Now traditionally, only functions used to create scopes 123

123

in JavaScript. 124

124

But starting in ES6, blocks also creates scopes now. 125

125

And with blocks, 126

126

we mean everything that is between curly braces, 127

127

such as the block of an if statement or a for loop. 128

128

So just like with functions, 129

129

variables declared inside a block 130

130

are only accessible inside that block 131

131

and not outside of it. 132

132

Now, the big difference is that block scopes 133

133

only apply to variables declared with let or const, okay? 134

134

So again, only let and const variables 135

135

are restricted to the block in which they were created. 136

136

That's why we say that let and const variables 137

137

are block scoped. 138

138

So if I declared a variable using var in this block, 139

139

then that variable would actually still be accessible 140

140

outside of the block, 141

141

and would be scoped to the current function 142

142

or to the global scope. 143

143

And so we say that var is function scoped. 144

144

So in ES5 and before, 145

145

we only had global scope and function scope. 146

146

And that's why ES5 variables declared with var, 147

147

only care about functions, but not about blocks. 148

148

They simply ignore them. 149

149

Finally, also starting in ES6, 150

150

all functions are now also block scoped, 151

151

at least in strict mode, 152

152

which you should always be using anyway. 153

153

And just like with let and const variables, 154

154

this means that functions declared inside a block 155

155

are only accessible inside that block, okay? 156

156

And we will see examples of all that in the next video, 157

157

when we're gonna go back to coding. 158

158

So to recap, let and const variables 159

159

as well as functions are block scoped. 160

160

And if you already know other programming languages, 161

161

block scoping is probably more in line 162

162

with what you already know. 163

163

Function scopes are weird for some beginners 164

164

in the JavaScript world. 165

165

And that's why block scopes were introduced in ES6. 166

166

But now to understand all this a little bit better, 167

167

let's actually look at a more real and detailed example 168

168

and also learn about the scope chain. 169

169

And here we have some code with different functions 170

170

and blocks, 171

171

and we're gonna take a look at the scopes 172

172

that are in this code as well as build the scope chain. 173

173

And of course, we start with the global scope. 174

174

As you can see, the myName variable 175

175

is the only variable declaration 176

176

that we have in the global scope. 177

177

Now, technically, the first function 178

178

also counts as a variable 179

179

that is present in the global scope, 180

180

but I want to keep it simple here. 181

181

And so I will only consider variable declarations 182

182

and no functions, all right? 183

183

Just keep in mind that whatever I'm explaining here 184

184

for variables also works the same for functions. 185

185

Anyway, inside the global scope, 186

186

we have a scope for the first function 187

187

because each function creates its own scope, remember? 188

188

And what's in the scope? 189

189

Well, it's to age variable that's declared 190

190

right at the top of the function. 191

191

Next inside the first scope, 192

192

let's now consider the second function, 193

193

which will also create its own scope 194

194

containing the job variable set to teacher. 195

195

So as you see, 196

196

we have a nested structure of scopes 197

197

with one scope inside the other. 198

198

But now comes the actually interesting part. 199

199

Because here in the second function, 200

200

we have this line of code 201

201

where we need the myName variable 202

202

and the age variable, 203

203

which were both not declared inside the current scope. 204

204

But we really need these variables here, 205

205

because otherwise we can't create this string here, right? 206

206

So how can this be fixed? 207

207

How will the JavaScript engine know the values 208

208

of these variables? 209

209

Well, the secret is that every scope 210

210

always has access to all the variables 211

211

from all its outer scopes. 212

212

So from all its parent scopes. 213

213

In our example, this means that the second scope 214

214

can access the age variable from the scope 215

215

of the first function. 216

216

Of course, this also means that the first scope 217

217

can access variables that are in the global scope, 218

218

because that is the parent scope. 219

219

As a consequence of this, 220

220

the second scope will then also be able to access 221

221

the myName variable from the global scope, 222

222

because it has access to the variables 223

223

from the first scope. 224

224

And by the way, all this also applies to function arguments. 225

225

But in this example, we just don't have any. 226

226

And this is essentially how the scope chain works. 227

227

In other words, 228

228

if one scope needs to use a certain variable, 229

229

but cannot find it in the current scope, 230

230

it will look up in the scope chain 231

231

and see if it can find a variable 232

232

in one of the parent scopes. 233

233

If it can, it will then use that variable. 234

234

And if it can't, then there will be an error. 235

235

And this process is called variable lookup. 236

236

Now it's important to note that these variables 237

237

are not copied from one scope to another, okay? 238

238

Instead, scopes simply look up in the scope chain 239

239

until they find a variable that they need 240

240

and then they use it. 241

241

What's also extremely important to note 242

242

is that this does not work the other way around. 243

243

A certain scope will never, ever have access 244

244

to the variables of an inner scope. 245

245

In this example, the first scope, for example, 246

246

will never get access to the job variable 247

247

that is stored in the second scope, okay? 248

248

So again, one scope can only look up in a scope chain, 249

249

but it cannot look down basically. 250

250

So only parent scope can be used, 251

251

but no child scopes. 252

252

Anyway, with all this in place now, 253

253

this line of code can be executed 254

254

and print to the console. 255

255

Jonas is a 30 year old teacher, 256

256

even though the myName and age variables 257

257

were not defined in the current scope. 258

258

All the engine did was to get them from the scope chain. 259

259

And as you might be noticing, 260

260

we have actually already done this before in our own code. 261

261

We just didn't really understand what was going on 262

262

and how it all worked. 263

263

But now we do know how it works. 264

264

Amazing, right? 265

265

Anyway, we still have one more scope left here, 266

266

and that's the one created by this block here. 267

267

Remember that starting with ES6, 268

268

not only functions create scopes, but also blocks. 269

269

However, these scopes only work for the ES6 variable types. 270

270

So for let and const variables. 271

271

That's why the only variable that's in the scope 272

272

is the decade variable. 273

273

The millennial variable isn't declared with const or let, 274

274

and therefore it is not scoped to just this block. 275

275

Instead, the millennial variable is actually part 276

276

of the first function scope. 277

277

So again, for a variable declared with var, 278

278

block scopes don't apply at all. 279

279

They are functions scoped, not block scoped. 280

280

Let and const on the other hand 281

281

are in fact blocks scoped, okay? 282

282

This is one of the fundamental things 283

283

that you need to keep in mind about let, const and var, 284

284

and about scoping in general. 285

285

So if you're taking notes and I hope you are taking 286

286

lots of notes, 287

287

then this must definitely be in there. 288

288

Now about a scope chain, 289

289

if the millennial variable is in the first function scope, 290

290

then of course the second function scope 291

291

also has access to it, 292

292

even if it doesn't really need that variable. 293

293

Also the scope chain does of course, 294

294

apply to block scopes as well. 295

295

And therefore in or if block scope, 296

296

we get access to all the variables 297

297

from all its outer scopes. 298

298

So from the first function scope, 299

299

and of course from the global scope. 300

300

That's why I said in the last slide 301

301

that variables in a global scope 302

302

are accessible from everywhere. 303

303

They are, because they are always 304

304

at the top of the scope chain. 305

305

In fact, we call variables in the global scope, 306

306

global variables, very creative, right? 307

307

But we actually use this term a lot in JavaScript. 308

308

Now it's important to understand 309

309

that our purple blocks scope 310

310

does not get access to any variables 311

311

from the yellow second function scope. 312

312

And the same, the other way around. 313

313

And why is that? 314

314

Well it's because of lexical scoping 315

315

as we learned in the last slide. 316

316

So the way that we can access variables 317

317

depends on where the scope is placed, 318

318

so where it is written in the code. 319

319

In this case, none of these two scopes is written 320

320

inside of one another. 321

321

They're both child scopes of the first function. 322

322

We could even say that they are a sibling scopes. 323

323

And so by the rules of lexical scoping, 324

324

they cannot have access to each others variables, 325

325

simply because one is not written inside the other one. 326

326

We can also say that the scope chain 327

327

only works upwards, not sideways. 328

328

Okay, so this was a lot to take in, 329

329

but I hope that everything's still keeps making sense 330

330

at this point. 331

331

And if not, don't worry, 332

332

we will see all this working in practice 333

333

in the next video. 334

334

But for now, though, 335

335

there is one more thing that we need to talk about, 336

336

which is the difference between the scope chain 337

337

and to call stack. 338

338

I get a lot of questions about this all the time. 339

339

And so I decided to talk about 340

340

how the call stack, execution context, 341

341

variable environments and scope 342

342

are all related to one another. 343

343

So before we move on to the next video. 344

344

And once more, 345

345

let's look at some more code here. 346

346

So we have three functions called first, second and third, 347

347

in order to make this easier to understand. 348

348

We start by calling the first function, 349

349

which then calls the second function, 350

350

which in turn calls the third function. 351

351

So from what we learned before, 352

352

the call stack for this example will look like this, right? 353

353

One execution context for each function 354

354

in the exact order in which they were called. 355

355

They also included the variable environment 356

356

of each execution context. 357

357

For now, all this has nothing to do with scopes 358

358

or the scope chain, all right? 359

359

All I'm doing is creating one execution context 360

360

for each function call and filling it 361

361

with the variables of that function. 362

362

And you can pause the video here for a moment 363

363

to understand the content of each variable environment. 364

364

Okay, and now that you did that 365

365

and we have all these variable environments in place, 366

366

we can actually start building the scope chain. 367

367

As always, we're gonna start with the global scope. 368

368

And the variables available in the global scope 369

369

are exactly the ones stored in the variable environment 370

370

of the global execution context. 371

371

And given everything we've learned so far, 372

372

that makes sense, right? 373

373

And note that in this example, 374

374

I am actually including functions in each scope 375

375

unlike we did in the previous slide. 376

376

Now in the global scope, we also call the first function, 377

377

which is the reason why we have an execution context for it 378

378

in the call stack. 379

379

And this function of course, also gets its own scope, 380

380

which contains all the variables that are declared 381

381

inside of the function. 382

382

And once again, this is exactly the same 383

383

as the variable environment 384

384

of the functions execution context. 385

385

However, that's not all 386

386

because now we already know about the scope chain. 387

387

So the first scope also gets access to all the variables 388

388

from its parent scope, 389

389

thanks to the scope chain. 390

390

Now, as we already know, 391

391

the scope chain is all about the order 392

392

in which functions are written in the code. 393

393

But what's really important to note here 394

394

is that the scope chain has nothing to do with the order 395

395

in which functions were called. 396

396

Or in other words, the scope chain has nothing to do 397

397

with the order of the execution contexts in the call stack. 398

398

The scope chain does get the variable environments 399

399

from the execution context as shown by the red arrows here, 400

400

but that's it. 401

401

The order of function calls is not relevant 402

402

to the scope chain at all, all right? 403

403

Really keep that in mind. 404

404

Now, moving on to the second function now, 405

405

once again, its scope is equal to its variable environment. 406

406

Also it's lexically written within the first function. 407

407

And so of course, 408

408

it will have access to all its parent scopes as well. 409

409

So we can say that the scope chain in a certain scope 410

410

is equal to adding together all the variable environments 411

411

of all the parent scopes. 412

412

And so this is our scope, 413

413

and the scope chain are built in the JavaScript engine 414

414

behind the scenes. 415

415

Okay. 416

416

Now in the second function, 417

417

we try to call the third function. 418

418

But why does that work? 419

419

Well, it works because the third function 420

420

is in the scope chain of the second function scope 421

421

as we can see here in our scope chain diagram. 422

422

It's a function in the global scope or a global function, 423

423

and therefore it's accessible everywhere. 424

424

Of course, this will create a new scope 425

425

along with the scope chain as we already know. 426

426

Great, so what happens in this third function? 427

427

Well, we're trying to act as variables B, C, 428

428

D and A here. 429

429

D is no problem because it's right there 430

430

in the third function scope. 431

431

So that one is easy. 432

432

Then variable C is not in a local scope 433

433

and so JavaScript needs to do a variable lookup. 434

434

So it looks up in a scope chain 435

435

looking for variable C, 436

436

but it's not there. 437

437

And of course it isn't, 438

438

because C is defined in the second function, 439

439

and there is just no way in which the third function 440

440

can access variables defined in the second function. 441

441

And that is true, 442

442

even though it was the second function who called the third. 443

443

And so here is even more proof 444

444

that the order in which functions are called 445

445

does not affect the scope chain at all. 446

446

And so here as a result, 447

447

we get the reference error 448

448

because both C and B cannot be found 449

449

in the third scope nor in the scope chain. 450

450

Okay. 451

451

And with this, I hope I made it crystal clear 452

452

that execution context, variable environments, 453

453

the call stack scope and the scope chain are all different, 454

454

but still very related concepts. 455

455

And if it's not yet crystal clear, 456

456

then it's no problem to maybe rewatch this slide, 457

457

or maybe even this entire lecture a little bit later. 458

458

And I know that this was quite a long lecture 459

459

with a ton of stuff to take in. 460

460

And so here is a handy summary 461

461

with the main takeaways from this video. 462

462

So to start, scoping asks the question, 463

463

"Where do variables live?" 464

464

Or "Where can we access a certain variable, 465

465

"and where not?" 466

466

That's what scoping is all about. 467

467

Now, there are three types scope in JavaScript. 468

468

The global scope, scopes defined by functions 469

469

and scopes defined by blocks, starting in ES6. 470

470

However, only let and const variables are block scoped. 471

471

Variables declared with var automatically end up 472

472

in the closest function scope. 473

473

Next in JavaScript, we have lexical scoping, 474

474

which means that the rules of where we can access variables 475

475

are based on where in the code functions 476

476

and blocks are written. 477

477

And now, let the magic begin, 478

478

because every scope always has access 479

479

to all the variables from all it's outer scopes. 480

480

And this is what we call the scope chain. 481

481

When a certain variable is not in the current scope, 482

482

the engine looks up in the scope chain 483

483

until it finds the variable that it's looking for, 484

484

and this process is called variable lookup. 485

485

It's important to note that the scope chain 486

486

is a one way street. 487

487

So a scope will never ever have access to the variables 488

488

of an inner scope, only of outer scopes. 489

489

We can also think of the scope chain in a certain scope 490

490

as being equal to adding together 491

491

all the variable environments of all the parent scopes. 492

492

And finally, we need to keep in mind 493

493

that the scope chain has nothing to do 494

494

with the order in which functions were called. 495

495

So the order of function calls 496

496

does not affect the scope chain at all. 497

497

Okay, and now that's actually it. 498

498

This is in a nutshell, scoping in JavaScript. 499

499

See you in the next video.

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