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