Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
1
00:00:01,180 --> 00:00:04,670
As we move towards the end of this section,
2
2
00:00:04,670 --> 00:00:06,940
we need to learn about the big difference
3
3
00:00:06,940 --> 00:00:10,030
between the way primitive types and objects
4
4
00:00:10,030 --> 00:00:12,467
are stored and memory.
5
5
00:00:12,467 --> 00:00:15,760
And this is actually a very practical aspect
6
6
00:00:15,760 --> 00:00:20,290
and one that causes a lot of confusion in beginners.
7
7
00:00:20,290 --> 00:00:24,230
So let's actually start by writing some code this time
8
8
00:00:24,230 --> 00:00:27,660
to understand what the confusion actually is,
9
9
00:00:27,660 --> 00:00:29,280
so that I can then show you
10
10
00:00:29,280 --> 00:00:31,483
how it all works behind the scenes.
11
11
00:00:33,200 --> 00:00:35,240
So right now I'm not gonna explain
12
12
00:00:35,240 --> 00:00:38,290
how the code we will right now works,
13
13
00:00:38,290 --> 00:00:43,040
but I will just show you what the source of confusion is.
14
14
00:00:43,040 --> 00:00:44,470
But for now let's start with
15
15
00:00:44,470 --> 00:00:47,480
a simple example with primitives.
16
16
00:00:47,480 --> 00:00:50,310
And so remember primitives are like numbers,
17
17
00:00:50,310 --> 00:00:52,503
strings, Boolean's, et cetera.
18
18
00:00:53,720 --> 00:00:56,273
So simply setting the age to 30,
19
19
00:00:57,609 --> 00:01:01,453
and then I'm creating a old age variable.
20
20
00:01:02,370 --> 00:01:04,620
And this one I will set to the age
21
21
00:01:04,620 --> 00:01:07,920
because now it is my birthday basically.
22
22
00:01:07,920 --> 00:01:10,890
And so my age changes to 31,
23
23
00:01:10,890 --> 00:01:14,130
but I still wanted to preserve my old age here
24
24
00:01:14,130 --> 00:01:15,490
in this variable.
25
25
00:01:15,490 --> 00:01:16,600
Okay?
26
26
00:01:16,600 --> 00:01:20,217
So let's log the results to the console now.
27
27
00:01:20,217 --> 00:01:25,217
And they should be pretty much what we expect at this point.
28
28
00:01:25,770 --> 00:01:30,350
So you see that my current age is 31 because, well,
29
29
00:01:30,350 --> 00:01:34,640
I changed the original one from 30 to 31.
30
30
00:01:34,640 --> 00:01:38,190
But the old age is still 30 here.
31
31
00:01:38,190 --> 00:01:41,880
And that's because I set it here at this point of the code
32
32
00:01:42,800 --> 00:01:46,770
to age, which was still 30 at this point.
33
33
00:01:46,770 --> 00:01:51,410
And so then changing the age here from 30 to 31
34
34
00:01:51,410 --> 00:01:55,120
did of course not affect the old age variable again.
35
35
00:01:55,120 --> 00:01:59,773
Again because at this point here age was still 30.
36
36
00:02:01,063 --> 00:02:06,063
All right, so here, hopefully there is not much confusion,
37
37
00:02:06,120 --> 00:02:09,000
everything works just as expected.
38
38
00:02:09,000 --> 00:02:12,913
But now let's create another scenario which has an object.
39
39
00:02:14,470 --> 00:02:17,563
So I'm simply going to create an object for me,
40
40
00:02:19,080 --> 00:02:23,443
with the name of Jonas and age 30.
41
41
00:02:25,220 --> 00:02:28,000
And now let's copy this object
42
42
00:02:28,000 --> 00:02:30,560
because let's say that I have a friend
43
43
00:02:30,560 --> 00:02:32,660
who's also called Jonas.
44
44
00:02:32,660 --> 00:02:36,510
And so instead of creating a brand new object from scratch,
45
45
00:02:36,510 --> 00:02:39,080
I would just copy the me object.
46
46
00:02:39,080 --> 00:02:43,637
So const Friend equals Me.
47
47
00:02:45,680 --> 00:02:46,530
Okay?
48
48
00:02:46,530 --> 00:02:50,240
And so now both the name and the age are the same,
49
49
00:02:50,240 --> 00:02:52,980
but let's say that we have different ages.
50
50
00:02:52,980 --> 00:02:56,120
And so let's change the age of my friend
51
51
00:02:57,220 --> 00:03:00,920
and that's pretty straightforward, right?
52
52
00:03:00,920 --> 00:03:04,610
So let's say that he is 27 years old.
53
53
00:03:04,610 --> 00:03:09,433
But of course we did not change me.age, right?
54
54
00:03:10,410 --> 00:03:15,410
So let's now take a look at both of them in the console.
55
55
00:03:16,980 --> 00:03:18,023
So first my friend,
56
56
00:03:20,850 --> 00:03:25,743
so that's the Friend object and then also Me,
57
57
00:03:26,730 --> 00:03:29,850
or we could say Jonas, it doesn't really matter.
58
58
00:03:29,850 --> 00:03:34,190
But what matters is that we will see the Me object
59
59
00:03:34,190 --> 00:03:37,610
and what do we think will happen now?
60
60
00:03:37,610 --> 00:03:39,800
So let me show it to you.
61
61
00:03:39,800 --> 00:03:43,290
And now we get that both me and my friend
62
62
00:03:43,290 --> 00:03:45,847
have the age of 27.
63
63
00:03:45,847 --> 00:03:49,530
And that looks a little bit strange because all we did
64
64
00:03:49,530 --> 00:03:53,540
was to change the age of the friend, right?
65
65
00:03:53,540 --> 00:03:57,760
Nowhere here, I have me.age equals 27,
66
66
00:03:57,760 --> 00:04:02,140
but still for myself, so here at the Me object,
67
67
00:04:02,140 --> 00:04:04,840
the age is also 27.
68
68
00:04:04,840 --> 00:04:08,980
And so that is what I mean by source of confusion.
69
69
00:04:08,980 --> 00:04:10,200
And so in this video,
70
70
00:04:10,200 --> 00:04:13,233
let's now find out why it works this way.
71
71
00:04:14,720 --> 00:04:18,700
Now, before we can understand the code that we just wrote,
72
72
00:04:18,700 --> 00:04:21,450
we need to review some basics here.
73
73
00:04:21,450 --> 00:04:23,363
First, we need to remember about
74
74
00:04:23,363 --> 00:04:25,900
JavaScripts primitive data types,
75
75
00:04:25,900 --> 00:04:30,900
which are number, string, Boolean, undefined, null, symbol,
76
76
00:04:31,060 --> 00:04:32,860
and BigInt.
77
77
00:04:32,860 --> 00:04:36,660
Then everything else are basically objects.
78
78
00:04:36,660 --> 00:04:40,900
So objects created with the object literal, arrays
79
79
00:04:40,900 --> 00:04:44,670
and even functions are all objects.
80
80
00:04:44,670 --> 00:04:48,660
Now, when we're talking about memory and memory management,
81
81
00:04:48,660 --> 00:04:52,010
it's usual to call primitives, primitive types
82
82
00:04:52,010 --> 00:04:56,260
and objects reference types because of the different way
83
83
00:04:56,260 --> 00:04:58,573
in which they are stored in memory.
84
84
00:04:59,410 --> 00:05:03,810
Next, we need to remember about the JavaScript engine.
85
85
00:05:03,810 --> 00:05:07,330
So the engine has two components, the call stack,
86
86
00:05:07,330 --> 00:05:11,470
where functions are executed and to heap where objects
87
87
00:05:11,470 --> 00:05:13,780
are stored in memory.
88
88
00:05:13,780 --> 00:05:16,710
And that's right, all of objects,
89
89
00:05:16,710 --> 00:05:19,510
or in other words, reference types
90
90
00:05:19,510 --> 00:05:23,020
will get stored right in the memory heap.
91
91
00:05:23,020 --> 00:05:26,780
And I mentioned that when we first talked about the engine,
92
92
00:05:26,780 --> 00:05:31,100
but now you will finally learn how that actually works.
93
93
00:05:31,100 --> 00:05:35,010
On the other hand, primitives or primitive types
94
94
00:05:35,010 --> 00:05:37,640
are stored in the call stack.
95
95
00:05:37,640 --> 00:05:40,650
And with that, I mean that primitive types
96
96
00:05:40,650 --> 00:05:43,680
are stored in the execution contexts
97
97
00:05:43,680 --> 00:05:45,830
in which they are declared.
98
98
00:05:45,830 --> 00:05:47,960
But for the sake of simplicity,
99
99
00:05:47,960 --> 00:05:50,220
let's ignore that detail now.
100
100
00:05:50,220 --> 00:05:52,600
And simply say that primitive types
101
101
00:05:52,600 --> 00:05:54,890
are stored in a call stack
102
102
00:05:54,890 --> 00:05:58,850
because that's where execution context run.
103
103
00:05:58,850 --> 00:06:03,030
All right, but now how does all that actually work?
104
104
00:06:03,030 --> 00:06:06,060
And why did our code example earlier behave
105
105
00:06:06,060 --> 00:06:08,220
in that weird way?
106
106
00:06:08,220 --> 00:06:09,953
Well, let's find out.
107
107
00:06:11,380 --> 00:06:14,860
So here we have the two code examples from earlier,
108
108
00:06:14,860 --> 00:06:19,380
as well as the engine with call stack and heap.
109
109
00:06:19,380 --> 00:06:24,020
And let's start by looking at the primitive values example.
110
110
00:06:24,020 --> 00:06:28,580
So when we declare a variable like age equals 30,
111
111
00:06:28,580 --> 00:06:32,060
what actually happens inside the JavaScript engine
112
112
00:06:32,060 --> 00:06:33,453
and the computer's memory?
113
113
00:06:34,390 --> 00:06:37,460
Well, first JavaScript will create
114
114
00:06:37,460 --> 00:06:42,140
a so-called unique identifier with the variable name.
115
115
00:06:42,140 --> 00:06:45,450
Then a piece of memory will be allocated
116
116
00:06:45,450 --> 00:06:49,778
with a certain address, so 0001 in this example,
117
117
00:06:49,778 --> 00:06:54,180
and finally the value would be stored in memory
118
118
00:06:54,180 --> 00:06:56,310
at the specified address.
119
119
00:06:56,310 --> 00:06:58,260
So in this case, the value 30
120
120
00:06:58,260 --> 00:07:02,463
will be specified at memory address 0001.
121
121
00:07:03,360 --> 00:07:06,400
And remember this all happens in a call stack
122
122
00:07:06,400 --> 00:07:08,653
where primitive values are stored.
123
123
00:07:09,570 --> 00:07:12,830
Now what's extremely important to understand here
124
124
00:07:12,830 --> 00:07:17,070
is that the identifier actually points to the address
125
125
00:07:17,070 --> 00:07:19,690
and not to the value itself.
126
126
00:07:19,690 --> 00:07:24,010
So we would say that the age variable is equal to 30,
127
127
00:07:24,010 --> 00:07:28,680
but in fact, age is equal to the memory address 0001,
128
128
00:07:30,420 --> 00:07:33,730
which holds the value of 30, all right?
129
129
00:07:33,730 --> 00:07:35,310
And this subtle distinction
130
130
00:07:35,310 --> 00:07:38,380
is very important to keep in mind.
131
131
00:07:38,380 --> 00:07:41,420
Now, in the next line, we declare old age
132
132
00:07:41,420 --> 00:07:43,540
to be equal to age.
133
133
00:07:43,540 --> 00:07:48,240
So knowing that a variable actually holds a memory address,
134
134
00:07:48,240 --> 00:07:51,200
what should old age look like?
135
135
00:07:51,200 --> 00:07:55,290
Well, it will simply point to the same memory address
136
136
00:07:55,290 --> 00:07:57,080
as the age variable.
137
137
00:07:57,080 --> 00:08:02,080
And so it will look like old age, is simply 30 as well.
138
138
00:08:02,140 --> 00:08:07,140
Great, but now in the next line, we set eight to 31.
139
139
00:08:07,160 --> 00:08:09,060
So what will happen then?
140
140
00:08:09,060 --> 00:08:12,070
The value at address 0001
141
141
00:08:12,070 --> 00:08:15,270
will certainly not become 31
142
142
00:08:15,270 --> 00:08:18,560
because that would change old age as well,
143
143
00:08:18,560 --> 00:08:21,560
since they both point to the same address.
144
144
00:08:21,560 --> 00:08:24,480
So that would make no sense at all.
145
145
00:08:24,480 --> 00:08:28,590
Also the value at a certain memory address is immutable,
146
146
00:08:28,590 --> 00:08:32,000
or in other words, it cannot be changed.
147
147
00:08:32,000 --> 00:08:34,630
So instead what's going to happen here
148
148
00:08:34,630 --> 00:08:38,190
is that a new piece of memory is allocated.
149
149
00:08:38,190 --> 00:08:42,477
So it's created and the age identifier now simply points
150
150
00:08:42,477 --> 00:08:47,023
to the new address, which is holding the new value of 31,
151
151
00:08:47,920 --> 00:08:48,753
all right?
152
152
00:08:48,753 --> 00:08:51,060
And that's why when we lock both
153
153
00:08:51,060 --> 00:08:53,720
or variables to the console in the end,
154
154
00:08:53,720 --> 00:08:58,050
they both return exactly values that we expect.
155
155
00:08:58,050 --> 00:09:02,200
Now with reference values, things work a bit differently,
156
156
00:09:02,200 --> 00:09:05,230
which is the reason why this example gave us
157
157
00:09:05,230 --> 00:09:09,910
that unexpected, weird behavior earlier in practice.
158
158
00:09:09,910 --> 00:09:14,590
So what's the origin of this weird unexpected result?
159
159
00:09:14,590 --> 00:09:19,590
Well, when a new object is created such as this Me object,
160
160
00:09:19,790 --> 00:09:21,930
it is stored in the heap.
161
161
00:09:21,930 --> 00:09:25,030
And such as before there is a memory address
162
162
00:09:25,030 --> 00:09:27,360
and then the value itself.
163
163
00:09:27,360 --> 00:09:29,710
Now in the case of reference values
164
164
00:09:29,710 --> 00:09:33,300
like this Me object the Me identifier
165
165
00:09:33,300 --> 00:09:35,920
does actually not point directly
166
166
00:09:35,920 --> 00:09:39,790
to this newly created memory address in the heap.
167
167
00:09:39,790 --> 00:09:43,360
So in this example, D30F,
168
168
00:09:43,360 --> 00:09:46,890
instead, it will point to a new piece of memory
169
169
00:09:46,890 --> 00:09:49,350
that's created in the stack.
170
170
00:09:49,350 --> 00:09:53,247
And this new piece of memory will then point to the object
171
171
00:09:53,247 --> 00:09:58,247
that's in the heap by using the memory address as its value.
172
172
00:09:59,220 --> 00:10:02,620
In other words, the piece of memory in the call stack
173
173
00:10:02,620 --> 00:10:06,290
has a reference to the piece of memory in the heap,
174
174
00:10:06,290 --> 00:10:09,810
which holds or Me object, okay?
175
175
00:10:09,810 --> 00:10:13,670
And that's the reason why we call objects reference types
176
176
00:10:13,670 --> 00:10:15,300
in this context.
177
177
00:10:15,300 --> 00:10:19,650
So again, when we declare a variable as an object,
178
178
00:10:19,650 --> 00:10:21,930
an identifier is created,
179
179
00:10:21,930 --> 00:10:25,130
which points to a piece of memory in the stack,
180
180
00:10:25,130 --> 00:10:29,010
which in turn points to a piece of memory in the heap.
181
181
00:10:29,010 --> 00:10:32,770
And that is where the object is actually stored.
182
182
00:10:32,770 --> 00:10:35,870
And it works this way because objects might be
183
183
00:10:35,870 --> 00:10:39,230
too large to be stored in the stack.
184
184
00:10:39,230 --> 00:10:42,210
Instead they are stored in the heap,
185
185
00:10:42,210 --> 00:10:45,620
which is like an almost unlimited memory pool.
186
186
00:10:45,620 --> 00:10:48,060
And the stack just keeps a reference
187
187
00:10:48,060 --> 00:10:51,610
to where the object is actually stored in the heap
188
188
00:10:51,610 --> 00:10:54,363
so that it can find it whenever necessary.
189
189
00:10:55,260 --> 00:10:57,390
Now, moving on in the code,
190
190
00:10:57,390 --> 00:11:00,540
we create a new variable called Friend
191
191
00:11:00,540 --> 00:11:03,900
that we set equal to the Me object.
192
192
00:11:03,900 --> 00:11:06,340
So what will happen here?
193
193
00:11:06,340 --> 00:11:09,570
Well, just like with primitive values,
194
194
00:11:09,570 --> 00:11:11,760
the Friend identifier will point
195
195
00:11:11,760 --> 00:11:16,560
to the exact same memory address as the Me identifier.
196
196
00:11:16,560 --> 00:11:20,000
And again, that address contains the reference,
197
197
00:11:20,000 --> 00:11:23,280
which then points to the object itself.
198
198
00:11:23,280 --> 00:11:27,010
And like this the Friend object is now essentially
199
199
00:11:27,010 --> 00:11:30,290
the exact same as the Me object.
200
200
00:11:30,290 --> 00:11:32,313
Do you see that here in the diagram?
201
201
00:11:33,230 --> 00:11:35,690
So here comes the interesting part
202
202
00:11:35,690 --> 00:11:38,870
because now we're actually gonna change a property
203
203
00:11:38,870 --> 00:11:43,870
in the Friend object by setting friend.age to 27.
204
204
00:11:44,420 --> 00:11:46,840
So what happens then is that the object
205
205
00:11:46,840 --> 00:11:51,800
is found in the heap, and the 30 is changed to 27.
206
206
00:11:51,800 --> 00:11:52,970
Great.
207
207
00:11:52,970 --> 00:11:56,410
And by the way, even though we defined the Friend variable
208
208
00:11:56,410 --> 00:12:01,170
as a constant, we can actually still manipulate the object
209
209
00:12:01,170 --> 00:12:03,100
without problems.
210
210
00:12:03,100 --> 00:12:06,180
And when we think about that, it makes sense
211
211
00:12:06,180 --> 00:12:09,840
because we're actually not changing the value in memory
212
212
00:12:09,840 --> 00:12:14,810
for the Friend identifier, it is still D30F.
213
213
00:12:14,810 --> 00:12:17,440
So the reference to the object.
214
214
00:12:17,440 --> 00:12:20,800
All we did was to change the value in the heap,
215
215
00:12:20,800 --> 00:12:22,690
and that's not a problem.
216
216
00:12:22,690 --> 00:12:26,230
So it's a misconception that all variables declared
217
217
00:12:26,230 --> 00:12:28,920
with const are immutable.
218
218
00:12:28,920 --> 00:12:32,610
In fact, that is only true for primitive values,
219
219
00:12:32,610 --> 00:12:35,200
but not for reference values.
220
220
00:12:35,200 --> 00:12:39,440
So keep that in mind, whenever you're working with const.
221
221
00:12:39,440 --> 00:12:43,000
Anyway, as we lock the Friend variable to the console,
222
222
00:12:43,000 --> 00:12:47,690
we get the age of 27, just as we said it before.
223
223
00:12:47,690 --> 00:12:50,350
But then when we lock the Me object,
224
224
00:12:50,350 --> 00:12:52,580
we get that weird behavior
225
225
00:12:52,580 --> 00:12:56,690
that we could previously not explain and not understand.
226
226
00:12:56,690 --> 00:12:59,750
But with everything that we learned in this lecture,
227
227
00:12:59,750 --> 00:13:01,520
it actually now makes sense
228
228
00:13:01,520 --> 00:13:05,950
that in the Me object, age is now also 27,
229
229
00:13:05,950 --> 00:13:10,100
even though we never changed me.age directly.
230
230
00:13:10,100 --> 00:13:13,410
And the reason for this, as we can see in this slide
231
231
00:13:13,410 --> 00:13:16,430
is the fact that Me and Friend
232
232
00:13:16,430 --> 00:13:21,400
actually point to the exact same object in the memory heap.
233
233
00:13:21,400 --> 00:13:24,370
So whenever we change something in this object,
234
234
00:13:24,370 --> 00:13:28,490
it will always be reflected in Friend and in Me.
235
235
00:13:28,490 --> 00:13:30,430
So in both these objects.
236
236
00:13:30,430 --> 00:13:34,040
So these are basically just two different identifiers
237
237
00:13:34,040 --> 00:13:36,960
pointing to the exact same value.
238
238
00:13:36,960 --> 00:13:40,907
And once again, that value is the memory address D30F
239
239
00:13:42,750 --> 00:13:46,800
which points to the reference in the memory heap.
240
240
00:13:46,800 --> 00:13:49,430
And one important implication of this
241
241
00:13:49,430 --> 00:13:53,330
is that whenever you think that you're copying an object,
242
242
00:13:53,330 --> 00:13:55,950
you're really just creating a new variable
243
243
00:13:55,950 --> 00:13:59,050
that points to the exact same object.
244
244
00:13:59,050 --> 00:14:01,380
And this has huge implications
245
245
00:14:01,380 --> 00:14:04,280
for the way JavaScript works in practice.
246
246
00:14:04,280 --> 00:14:06,760
And we will see that in the next video
247
247
00:14:06,760 --> 00:14:08,670
and throughout the course.
248
248
00:14:08,670 --> 00:14:11,450
Now there are actually ways around this,
249
249
00:14:11,450 --> 00:14:13,600
as we will also learn later.
250
250
00:14:13,600 --> 00:14:17,020
but in general, this is how reference values work
251
251
00:14:17,020 --> 00:14:18,580
in JavaScript.
252
252
00:14:18,580 --> 00:14:21,370
So make sure to really understand this,
253
253
00:14:21,370 --> 00:14:25,170
as well as the implications that this behavior has,
254
254
00:14:25,170 --> 00:14:28,620
even if that means that you have to re-watch this lecture
255
255
00:14:28,620 --> 00:14:33,570
or at least the explanation of this slide, all right?
256
256
00:14:33,570 --> 00:14:36,570
Then once you really understand what happened here,
257
257
00:14:36,570 --> 00:14:40,260
in this example, let's understand primitive values
258
258
00:14:40,260 --> 00:14:43,430
and reference values even better in practice
259
259
00:14:43,430 --> 00:14:44,843
in the next lecture.
260
260
00:14:45,900 --> 00:14:49,750
But before we do that, let me just quickly take a second
261
261
00:14:49,750 --> 00:14:52,920
and mention a three more, really big topics
262
262
00:14:52,920 --> 00:14:56,100
about how JavaScript works behind the scenes
263
263
00:14:56,100 --> 00:14:58,250
that will not be in the section,
264
264
00:14:58,250 --> 00:15:02,400
but closer to where we actually need to learn about them.
265
265
00:15:02,400 --> 00:15:06,220
For example, one fundamental concept of JavaScript
266
266
00:15:06,220 --> 00:15:08,710
is prototypal inheritance.
267
267
00:15:08,710 --> 00:15:10,690
But we will only talk about that
268
268
00:15:10,690 --> 00:15:14,610
in the object oriented programming section of this course.
269
269
00:15:14,610 --> 00:15:18,110
Because it doesn't make sense to learn about this now
270
270
00:15:18,110 --> 00:15:20,550
only to then forget it all
271
271
00:15:20,550 --> 00:15:23,083
until we finally reach that section.
272
272
00:15:23,960 --> 00:15:28,930
The same is true for a detailed lecture on the event loop.
273
273
00:15:28,930 --> 00:15:32,720
So I already introduced the event loop in this section,
274
274
00:15:32,720 --> 00:15:36,080
but in the section about asynchronous JavaScript,
275
275
00:15:36,080 --> 00:15:38,010
we will dive really deep into
276
276
00:15:38,010 --> 00:15:40,370
how exactly the event loop works
277
277
00:15:40,370 --> 00:15:42,910
and why it's such a fundamental piece
278
278
00:15:42,910 --> 00:15:44,393
of the JavaScript engine.
279
279
00:15:45,270 --> 00:15:47,390
Finally, we will have lectures on
280
280
00:15:47,390 --> 00:15:51,100
how the DOM actually works behind the scenes too.
281
281
00:15:51,100 --> 00:15:52,430
And that's going to be
282
282
00:15:52,430 --> 00:15:55,530
in the advanced DOM and events section
283
283
00:15:55,530 --> 00:15:57,160
so that you can then apply
284
284
00:15:57,160 --> 00:16:00,000
what you learned there right away.
285
285
00:16:00,000 --> 00:16:01,190
Okay?
286
286
00:16:01,190 --> 00:16:03,893
And with that being said, let's now move on.
25358
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.