1
00:00:01,120 --> 00:00:03,650
<v Jonas>So I talked about the JavaScript engine</v>

2
00:00:03,650 --> 00:00:08,040
in the last lecture, but what is that engine actually?

3
00:00:08,040 --> 00:00:10,830
And what is a JavaScript runtime?

4
00:00:10,830 --> 00:00:15,700
Also, how is JavaScript code translated to a machine code?

5
00:00:15,700 --> 00:00:17,470
So that's just some of the topics

6
00:00:17,470 --> 00:00:19,550
that we talked about in the last video.

7
00:00:19,550 --> 00:00:23,483
And so now let's find out how they work in this lecture.

8
00:00:24,900 --> 00:00:27,660
So a JavaScript engine is simply

9
00:00:27,660 --> 00:00:31,740
a computer program that executes JavaScript code.

10
00:00:31,740 --> 00:00:35,080
There are a lot of steps involved in doing that,

11
00:00:35,080 --> 00:00:38,050
but essentially executing JavaScript code

12
00:00:38,050 --> 00:00:40,590
is what an engine does.

13
00:00:40,590 --> 00:00:44,200
Now every browser has its own JavaScript engine

14
00:00:44,200 --> 00:00:49,090
but probably the most well known engine is Google's V-Eight.

15
00:00:49,090 --> 00:00:51,720
The V eight engine powers Google Chrome,

16
00:00:51,720 --> 00:00:55,730
but also Node.js which is that JavaScript runtime

17
00:00:55,730 --> 00:00:58,630
that we talked about in the beginning of the course,

18
00:00:58,630 --> 00:01:02,560
so the one that we can use to build server side applications

19
00:01:02,560 --> 00:01:06,990
with JavaScript, so outside of any browser.

20
00:01:06,990 --> 00:01:09,290
And of course all the other browsers

21
00:01:09,290 --> 00:01:11,510
have their own JavaScript engines

22
00:01:11,510 --> 00:01:15,310
which you can look up online if you're interested.

23
00:01:15,310 --> 00:01:19,430
Anyway, it's quite easy to understand what an engine is

24
00:01:19,430 --> 00:01:22,610
but what's most important is to actually understand

25
00:01:22,610 --> 00:01:25,900
its components and how it works.

26
00:01:25,900 --> 00:01:29,030
So any JavaScript engine always contains

27
00:01:29,030 --> 00:01:32,040
a call stack and a heap.

28
00:01:32,040 --> 00:01:36,250
The call stack is where our code is actually executed

29
00:01:36,250 --> 00:01:39,149
using something called execution contexts.

30
00:01:39,149 --> 00:01:42,880
Then the heap is an unstructured memory pool

31
00:01:42,880 --> 00:01:47,420
which stores all the objects that our application needs.

32
00:01:47,420 --> 00:01:50,770
Alright, so with this look at the engine,

33
00:01:50,770 --> 00:01:54,080
we have answered where our code is executed.

34
00:01:54,080 --> 00:01:55,670
But now the question is

35
00:01:55,670 --> 00:01:58,830
how the code is compiled to machine code

36
00:01:58,830 --> 00:02:02,560
so that it actually can be executed afterwards.

37
00:02:02,560 --> 00:02:04,403
Well, let's find out.

38
00:02:05,600 --> 00:02:07,040
But first we need to make

39
00:02:07,040 --> 00:02:09,780
a quick computer science side note here

40
00:02:09,780 --> 00:02:11,550
and talk about the difference between

41
00:02:11,550 --> 00:02:14,530
compilation and interpretation.

42
00:02:14,530 --> 00:02:15,900
So in the last lecture,

43
00:02:15,900 --> 00:02:18,660
we learned that the computer's processor

44
00:02:18,660 --> 00:02:21,630
only understands zeros and ones

45
00:02:21,630 --> 00:02:25,040
and that's therefore every single computer program

46
00:02:25,040 --> 00:02:29,220
ultimately needs to be converted into this machine code

47
00:02:29,220 --> 00:02:33,860
and this can happen using compilation or interpretation.

48
00:02:33,860 --> 00:02:36,880
So in compilation, the entire source code

49
00:02:36,880 --> 00:02:39,890
is converted into machine code at once.

50
00:02:39,890 --> 00:02:42,520
And this machine code is then written

51
00:02:42,520 --> 00:02:47,440
into a portable file that can be executed on any computer.

52
00:02:47,440 --> 00:02:49,980
So we have two different steps here.

53
00:02:49,980 --> 00:02:52,200
First, the machine code is built

54
00:02:52,200 --> 00:02:56,870
and then it is executed in the CPU so in the processor.

55
00:02:56,870 --> 00:02:58,510
And the execution can happen

56
00:02:58,510 --> 00:03:01,390
way after the compilation of course.

57
00:03:01,390 --> 00:03:04,080
For example, any application that you're using

58
00:03:04,080 --> 00:03:08,210
on your computer right now has been compiled before

59
00:03:08,210 --> 00:03:11,883
and you're now executing it way after it's compilation.

60
00:03:12,740 --> 00:03:15,960
Now, on the other hand in interpretation,

61
00:03:15,960 --> 00:03:19,990
there is an interpreter which runs through the source code

62
00:03:19,990 --> 00:03:22,840
and executes it line by line.

63
00:03:22,840 --> 00:03:27,010
So here we do not have the same two steps as before.

64
00:03:27,010 --> 00:03:32,010
Instead the code is read and executed all at the same time.

65
00:03:32,230 --> 00:03:34,650
Of course the source code still

66
00:03:34,650 --> 00:03:37,430
needs to be converted into machine code,

67
00:03:37,430 --> 00:03:40,810
but it simply happens right before it's executed

68
00:03:40,810 --> 00:03:43,320
and not ahead of time.

69
00:03:43,320 --> 00:03:47,580
Now JavaScript used to be a purely interpreted language

70
00:03:47,580 --> 00:03:50,170
but the problem with interpreted languages

71
00:03:50,170 --> 00:03:54,630
is that they are much, much slower than compiled languages.

72
00:03:54,630 --> 00:03:57,450
This used to be okay for JavaScript,

73
00:03:57,450 --> 00:03:59,770
but now with modern JavaScript

74
00:03:59,770 --> 00:04:02,890
and fully fledged web applications that we built

75
00:04:02,890 --> 00:04:07,890
and use today, low performance is no longer acceptable.

76
00:04:07,930 --> 00:04:11,050
Just imagine you were using Google maps in your browser

77
00:04:11,050 --> 00:04:14,200
and you were dragging the map and each time you dragged

78
00:04:14,200 --> 00:04:17,370
it would take one second for it to move.

79
00:04:17,370 --> 00:04:20,815
That would be completely unacceptable, right?

80
00:04:20,815 --> 00:04:23,060
Now many people still think

81
00:04:23,060 --> 00:04:25,760
that JavaScript is an interpreted language

82
00:04:25,760 --> 00:04:28,410
but that's not really true anymore.

83
00:04:28,410 --> 00:04:31,380
So instead of simple interpretation

84
00:04:31,380 --> 00:04:34,690
modern JavaScript engine now use a mix between

85
00:04:34,690 --> 00:04:37,370
compilation and interpretation

86
00:04:37,370 --> 00:04:41,140
which is called just-in-time compilation.

87
00:04:41,140 --> 00:04:44,130
This approach basically compiles the entire code

88
00:04:44,130 --> 00:04:48,830
into machine code at once and then executes it right away.

89
00:04:48,830 --> 00:04:50,680
So we still have the two steps

90
00:04:50,680 --> 00:04:53,960
of regular ahead of time compilation

91
00:04:53,960 --> 00:04:57,240
but there is no portable file to execute.

92
00:04:57,240 --> 00:05:01,720
And the execution happens immediately after a compilation.

93
00:05:01,720 --> 00:05:04,370
And this is perfect for JavaScript

94
00:05:04,370 --> 00:05:08,350
as it's really a lot faster than just executing code

95
00:05:08,350 --> 00:05:10,250
line by line.

96
00:05:10,250 --> 00:05:13,360
Now I skimmed over some details here

97
00:05:13,360 --> 00:05:16,120
but this is really all you need to know.

98
00:05:16,120 --> 00:05:19,130
Anyway, let's now understand how this works

99
00:05:19,130 --> 00:05:22,023
in the particular case of JavaScript.

100
00:05:23,840 --> 00:05:27,627
So as a piece of JavaScript code enters the engine

101
00:05:27,627 --> 00:05:31,040
the first step is to parse the code

102
00:05:31,040 --> 00:05:34,400
which essentially means to read the code.

103
00:05:34,400 --> 00:05:37,850
During the parsing process, the code is parsed

104
00:05:37,850 --> 00:05:39,850
into a data structure called

105
00:05:39,850 --> 00:05:43,630
the abstract syntax tree or AST.

106
00:05:43,630 --> 00:05:46,670
This works by first splitting up each line of code

107
00:05:46,670 --> 00:05:49,730
into pieces that are meaningful to the language

108
00:05:49,730 --> 00:05:52,490
like the const or function keywords,

109
00:05:52,490 --> 00:05:54,500
and then saving all these pieces

110
00:05:54,500 --> 00:05:57,570
into the tree in a structured way.

111
00:05:57,570 --> 00:06:01,590
This step also checks if there are any syntax errors

112
00:06:01,590 --> 00:06:04,250
and the resulting tree will later be used

113
00:06:04,250 --> 00:06:06,840
to generate the machine code.

114
00:06:06,840 --> 00:06:09,890
Now let's say we have a very simple program.

115
00:06:09,890 --> 00:06:13,800
All it does is to declare a variable like this,

116
00:06:13,800 --> 00:06:15,900
and this is what the AST

117
00:06:15,900 --> 00:06:19,560
for just this one line of code looks like.

118
00:06:19,560 --> 00:06:21,900
So we have a variable declaration

119
00:06:21,900 --> 00:06:23,900
which should be a constant

120
00:06:23,900 --> 00:06:28,500
with the name X and the value of 23.

121
00:06:28,500 --> 00:06:32,050
And besides that there is a lot of other stuff here,

122
00:06:32,050 --> 00:06:33,620
as you can see.

123
00:06:33,620 --> 00:06:35,930
So just imagine what it would look like

124
00:06:35,930 --> 00:06:38,910
for a large real application.

125
00:06:38,910 --> 00:06:41,230
And of course you don't need to know

126
00:06:41,230 --> 00:06:43,520
what an AST looks like.

127
00:06:43,520 --> 00:06:46,990
This is just for curiosity okay.

128
00:06:46,990 --> 00:06:48,850
Now sometimes I get asked

129
00:06:48,850 --> 00:06:53,030
if this tree has anything to do with the DOM tree

130
00:06:53,030 --> 00:06:56,220
and the answer is a very clear no.

131
00:06:56,220 --> 00:07:00,550
So this tree has absolutely nothing to do with the DOM.

132
00:07:00,550 --> 00:07:03,310
It is not related in any way.

133
00:07:03,310 --> 00:07:05,060
It's just a representation

134
00:07:05,060 --> 00:07:08,662
of our entire code inside the engine.

135
00:07:08,662 --> 00:07:11,940
Anyway, the next step is compilation

136
00:07:11,940 --> 00:07:14,610
which takes the generated AST

137
00:07:14,610 --> 00:07:17,330
and compiles it into machine code

138
00:07:17,330 --> 00:07:20,290
just as we learned in the previous slide.

139
00:07:20,290 --> 00:07:24,100
This machine code then gets executed right away

140
00:07:24,100 --> 00:07:27,720
because remember modern JavaScript engine use

141
00:07:27,720 --> 00:07:30,180
just-in-time compilation.

142
00:07:30,180 --> 00:07:32,770
And remember execution happens

143
00:07:32,770 --> 00:07:35,670
in the JavaScript engines call stack

144
00:07:35,670 --> 00:07:39,600
but we will dig deeper into this in the next lecture.

145
00:07:39,600 --> 00:07:42,210
All right, so far so good.

146
00:07:42,210 --> 00:07:46,180
We have our code running so we can finish here, Right?

147
00:07:46,180 --> 00:07:50,120
Well, not so fast because modern JavaScript engines

148
00:07:50,120 --> 00:07:54,110
actually have some pretty clever optimization strategies.

149
00:07:54,110 --> 00:07:57,870
What they do is to create a very unoptimized version

150
00:07:57,870 --> 00:07:59,800
of machine code in the beginning

151
00:07:59,800 --> 00:08:04,400
just so that it can start executing as fast as possible.

152
00:08:04,400 --> 00:08:07,840
Then in the background, this code is being optimized

153
00:08:07,840 --> 00:08:12,840
and recompiled during the already running program execution.

154
00:08:12,900 --> 00:08:15,060
And this can be done most of the times

155
00:08:15,060 --> 00:08:17,170
and after each optimization

156
00:08:17,170 --> 00:08:20,240
the unoptimized code is simply swept

157
00:08:20,240 --> 00:08:22,790
for the new more optimized code

158
00:08:22,790 --> 00:08:26,000
without ever stopping execution of course.

159
00:08:26,000 --> 00:08:29,300
And this process is what makes modern engines

160
00:08:29,300 --> 00:08:32,720
such as the V-Eight so fast

161
00:08:32,720 --> 00:08:36,480
and all this parsing, compilation and optimization

162
00:08:36,480 --> 00:08:40,183
happens in some special threads inside the engine

163
00:08:40,183 --> 00:08:42,730
that we cannot access from our code.

164
00:08:42,730 --> 00:08:45,850
So completely separate from the main thread

165
00:08:45,850 --> 00:08:48,310
that is basically running into call stack

166
00:08:48,310 --> 00:08:50,910
executing our own code.

167
00:08:50,910 --> 00:08:55,250
Now different engines implements in slightly different ways,

168
00:08:55,250 --> 00:08:58,220
but in a nutshell this is what modern

169
00:08:58,220 --> 00:09:02,700
just-in-time compilation looks like for JavaScript.

170
00:09:02,700 --> 00:09:04,720
And the next time someone tells you

171
00:09:04,720 --> 00:09:07,490
JavaScript is an interpreted language,

172
00:09:07,490 --> 00:09:10,550
you just show them this slide so that they can learn

173
00:09:10,550 --> 00:09:12,053
how it really works.

174
00:09:13,280 --> 00:09:16,720
Alright, so we looked at the JavaScript engine

175
00:09:16,720 --> 00:09:20,740
and how it works behind the scenes in quite some detail.

176
00:09:20,740 --> 00:09:23,060
Now to round off this lecture

177
00:09:23,060 --> 00:09:27,050
let's also take a look at what a JavaScript runtime is.

178
00:09:27,050 --> 00:09:29,680
And in particular, the most common one,

179
00:09:29,680 --> 00:09:32,470
which is the browser and by doing this,

180
00:09:32,470 --> 00:09:34,200
we can get the bigger picture

181
00:09:34,200 --> 00:09:38,750
of how all the pieces fit together when we use JavaScript.

182
00:09:38,750 --> 00:09:41,560
And so this is a really important slide.

183
00:09:41,560 --> 00:09:46,480
So we can imagine a JavaScript runtime as a big box

184
00:09:46,480 --> 00:09:48,250
or a big container

185
00:09:48,250 --> 00:09:50,860
which includes all the things that we need

186
00:09:50,860 --> 00:09:55,330
in order to use JavaScript in this case, in the browser.

187
00:09:55,330 --> 00:09:58,197
And to heart of any JavaScript,

188
00:09:58,197 --> 00:10:01,120
runtime is always a JavaScript engine.

189
00:10:01,120 --> 00:10:04,490
So exactly the one we've been talking about.

190
00:10:04,490 --> 00:10:07,570
That's why it makes sense to talk about engines

191
00:10:07,570 --> 00:10:09,690
and runtimes together.

192
00:10:09,690 --> 00:10:12,510
Without an engine there is no runtime

193
00:10:12,510 --> 00:10:15,710
and there is no JavaScript at all.

194
00:10:15,710 --> 00:10:19,500
However the engine alone is not enough.

195
00:10:19,500 --> 00:10:21,470
In order to work properly,

196
00:10:21,470 --> 00:10:24,990
we also need access to the web APIs,

197
00:10:24,990 --> 00:10:28,480
and we talked about web APIs before, remember?

198
00:10:28,480 --> 00:10:31,160
So that's everything related to the DOM

199
00:10:31,160 --> 00:10:36,160
or timers or even the console.log that we use all the time.

200
00:10:36,420 --> 00:10:40,890
So essentially web APIs are functionalities provided

201
00:10:40,890 --> 00:10:42,200
to the engine,

202
00:10:42,200 --> 00:10:44,450
but which are actually not part

203
00:10:44,450 --> 00:10:47,060
of the JavaScript language itself.

204
00:10:47,060 --> 00:10:50,550
JavaScript simply gets access to these APIs

205
00:10:50,550 --> 00:10:53,020
through the global window object.

206
00:10:53,020 --> 00:10:55,720
But it still makes sense that the web APIs

207
00:10:55,720 --> 00:10:58,170
are also part of the runtime,

208
00:10:58,170 --> 00:11:02,460
because again a runtime is just like a box

209
00:11:02,460 --> 00:11:07,050
that contains all the JavaScript related stuff that we need.

210
00:11:07,050 --> 00:11:09,640
Next a typical JavaScript runtime

211
00:11:09,640 --> 00:11:13,300
also includes a so called callback queue.

212
00:11:13,300 --> 00:11:15,840
This is a data structure that contains

213
00:11:15,840 --> 00:11:20,180
all the callback functions that are ready to be executed.

214
00:11:20,180 --> 00:11:23,350
For example we attach event handler functions

215
00:11:23,350 --> 00:11:26,010
to DOM elements like a button

216
00:11:26,010 --> 00:11:28,860
to react to certain events, right?

217
00:11:28,860 --> 00:11:30,700
And these event handler functions

218
00:11:30,700 --> 00:11:34,540
are also called callback functions okay.

219
00:11:34,540 --> 00:11:36,570
So as the event happens,

220
00:11:36,570 --> 00:11:40,900
for example a click, the callback function will be called.

221
00:11:40,900 --> 00:11:44,240
And here is how that actually works behind the scenes.

222
00:11:44,240 --> 00:11:47,900
So the first thing that actually happens after the event

223
00:11:47,900 --> 00:11:50,310
is that the callback function is put

224
00:11:50,310 --> 00:11:52,340
into the callback queue.

225
00:11:52,340 --> 00:11:54,430
Then when the stack is empty

226
00:11:54,430 --> 00:11:57,980
the callback function is passed to the stack

227
00:11:57,980 --> 00:12:00,690
so that it can be executed.

228
00:12:00,690 --> 00:12:04,430
And this happens by something called the event loop.

229
00:12:04,430 --> 00:12:07,430
So basically the event loop takes callback functions

230
00:12:07,430 --> 00:12:08,960
from the callback queue

231
00:12:08,960 --> 00:12:11,150
and puts them in the call stack

232
00:12:11,150 --> 00:12:13,850
so that they can be executed.

233
00:12:13,850 --> 00:12:16,570
And remember how I said in the last lecture

234
00:12:16,570 --> 00:12:17,550
that the event loop

235
00:12:17,550 --> 00:12:21,000
is how JavaScript's nonblocking concurrency model

236
00:12:21,000 --> 00:12:22,740
is implemented?

237
00:12:22,740 --> 00:12:26,830
Well, here is an overview of how that works.

238
00:12:26,830 --> 00:12:31,380
Now we will go over why this makes JavaScript nonblocking

239
00:12:31,380 --> 00:12:33,900
in a special lecture about the event loop

240
00:12:33,900 --> 00:12:35,200
later in the course,

241
00:12:35,200 --> 00:12:37,760
because this is really a fundamental piece

242
00:12:37,760 --> 00:12:39,770
of JavaScript development

243
00:12:39,770 --> 00:12:43,083
that every developer needs to understand deeply.

244
00:12:44,180 --> 00:12:48,560
Alright, so as they already said the focus in this course

245
00:12:48,560 --> 00:12:51,100
is on JavaScript in the browser

246
00:12:51,100 --> 00:12:55,660
and that's why we analyzed the browser JavaScript runtime.

247
00:12:55,660 --> 00:12:58,120
However, it's also important to remember

248
00:12:58,120 --> 00:13:01,630
that JavaScript can exist outside of browsers,

249
00:13:01,630 --> 00:13:03,830
for example, in Node.js.

250
00:13:03,830 --> 00:13:07,440
And so here is what the node JS JavaScript runtime

251
00:13:07,440 --> 00:13:08,880
looks like.

252
00:13:08,880 --> 00:13:12,300
It's pretty similar, but since we don't have a browser

253
00:13:12,300 --> 00:13:15,360
of course, we can't have the web APIs

254
00:13:15,360 --> 00:13:18,450
because it's the browser who provides these.

255
00:13:18,450 --> 00:13:21,970
Instead we have multiple C ++ bindings

256
00:13:21,970 --> 00:13:24,570
and a so called thread pool.

257
00:13:24,570 --> 00:13:27,110
Now details don't matter here at all.

258
00:13:27,110 --> 00:13:28,470
I just want you to know

259
00:13:28,470 --> 00:13:32,200
that different JavaScript runtimes do exist.

260
00:13:32,200 --> 00:13:35,460
Alright cool, that's all I had to tell you

261
00:13:35,460 --> 00:13:39,010
about JavaScript engines and runtimes.

262
00:13:39,010 --> 00:13:43,260
In our next lecture we will learn how JavaScript is executed

263
00:13:43,260 --> 00:13:44,533
in the call stack.

