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