WEBVTT

1
00:00:01.280 --> 00:00:06.110
<v ->So we learned about constructor functions and ESX classes.</v>

2
00:00:06.110 --> 00:00:08.380
But there is actually a third way

3
00:00:08.380 --> 00:00:12.440
of implementing prototypal inheritance or delegation,

4
00:00:12.440 --> 00:00:14.540
as we can also call it.

5
00:00:14.540 --> 00:00:16.540
And that third way is

6
00:00:16.540 --> 00:00:20.060
to use a function called Object.create,

7
00:00:20.060 --> 00:00:22.810
which works in a pretty different way

8
00:00:22.810 --> 00:00:25.793
than constructor functions and classes work.

9
00:00:27.770 --> 00:00:30.150
Now, with Object.create,

10
00:00:30.150 --> 00:00:34.200
there is still the idea of prototypal inheritance.

11
00:00:34.200 --> 00:00:38.240
However, there are no prototype properties involved.

12
00:00:38.240 --> 00:00:43.220
And also no constructor functions, and no new operator.

13
00:00:43.220 --> 00:00:46.870
So instead, we can use Object.create

14
00:00:46.870 --> 00:00:51.200
to essentially manually set the prototype of an object,

15
00:00:51.200 --> 00:00:54.450
to any other object that we want.

16
00:00:54.450 --> 00:00:59.240
Okay, so if we can set the prototype to any object,

17
00:00:59.240 --> 00:01:01.293
let's actually create an object

18
00:01:01.293 --> 00:01:05.710
that we want to be the prototype of all the person objects.

19
00:01:05.710 --> 00:01:09.030
So essentially, let's recreate the person class

20
00:01:09.030 --> 00:01:14.030
from earlier, so let's say, person,

21
00:01:14.740 --> 00:01:16.910
and I'm calling it person PersonProto,

22
00:01:16.910 --> 00:01:18.960
which stands for prototype.

23
00:01:18.960 --> 00:01:20.480
Because, again,

24
00:01:20.480 --> 00:01:23.720
this object is gonna be literally the prototype

25
00:01:23.720 --> 00:01:25.533
of all the person objects.

26
00:01:27.760 --> 00:01:32.090
And now, this is actually just a simple object literal.

27
00:01:32.090 --> 00:01:34.973
And so now, what should we actually put in here?

28
00:01:36.380 --> 00:01:39.130
We're gonna put exactly what we put before

29
00:01:39.130 --> 00:01:41.460
into the prototype property.

30
00:01:41.460 --> 00:01:44.413
And so that was the CalcAge method.

31
00:01:46.100 --> 00:01:49.790
So we did that, actually here first manually.

32
00:01:49.790 --> 00:01:54.510
So we added CalcAge to the prototype property of person.

33
00:01:54.510 --> 00:01:56.793
And then here, we also did that,

34
00:01:58.130 --> 00:02:00.700
but in a more implicit way.

35
00:02:00.700 --> 00:02:04.310
So JavaScript did that for us behind the scenes.

36
00:02:04.310 --> 00:02:06.780
But now let's take this function here.

37
00:02:06.780 --> 00:02:08.940
Or actually, we can take all of this,

38
00:02:08.940 --> 00:02:12.480
because we can also write methods in this way,

39
00:02:12.480 --> 00:02:13.993
in object literals.

40
00:02:15.160 --> 00:02:17.593
And so that's actually it.

41
00:02:18.970 --> 00:02:20.400
That's all the methods

42
00:02:20.400 --> 00:02:23.540
that we want the person objects to inherit.

43
00:02:23.540 --> 00:02:25.760
And so we put them in the prototype.

44
00:02:25.760 --> 00:02:27.193
And now all we need to do is

45
00:02:27.193 --> 00:02:29.780
to actually create a person object

46
00:02:29.780 --> 00:02:33.630
with this object here as the prototype.

47
00:02:33.630 --> 00:02:36.773
And for that, we can use Object.create.

48
00:02:38.130 --> 00:02:40.683
So let's create a person called Steven here.

49
00:02:42.620 --> 00:02:45.333
And so now, Object.create.

50
00:02:46.220 --> 00:02:49.040
And here we pass in the object that we want

51
00:02:49.040 --> 00:02:51.903
to be the prototype of the new object.

52
00:02:53.380 --> 00:02:56.793
So that's PersonProto.

53
00:02:57.770 --> 00:03:00.538
And so this will now return a brand new object,

54
00:03:00.538 --> 00:03:05.060
that is linked to the prototype that we passed in here.

55
00:03:05.060 --> 00:03:09.390
So Steven here is right now an empty object.

56
00:03:09.390 --> 00:03:13.190
And it will be linked to this PersonProto object,

57
00:03:13.190 --> 00:03:15.810
which will be its prototype.

58
00:03:15.810 --> 00:03:17.930
And we can actually already see

59
00:03:17.930 --> 00:03:19.323
that here in the console.

60
00:03:20.570 --> 00:03:23.820
So as I said, For now, it is empty.

61
00:03:23.820 --> 00:03:26.250
But we already have the prototype.

62
00:03:26.250 --> 00:03:28.603
And in there, we see we have CalcAge.

63
00:03:31.920 --> 00:03:35.860
But now we don't have any properties on the object yet.

64
00:03:35.860 --> 00:03:38.850
So let's quickly fix that.

65
00:03:38.850 --> 00:03:42.000
So Stephen.name.

66
00:03:42.000 --> 00:03:43.230
So I'm doing it here,

67
00:03:43.230 --> 00:03:47.323
just like I would do in any other object literal.

68
00:03:49.070 --> 00:03:51.743
And so this is not ideal, of course.

69
00:03:52.900 --> 00:03:55.700
But we're gonna fix that in a minute.

70
00:03:55.700 --> 00:03:59.470
Because of course, we want actually a programmatic way

71
00:03:59.470 --> 00:04:01.370
of creating new objects,

72
00:04:01.370 --> 00:04:03.723
instead of having to do it like this.

73
00:04:04.560 --> 00:04:05.570
But again, for now,

74
00:04:05.570 --> 00:04:08.390
we are just worried about the prototypes

75
00:04:08.390 --> 00:04:10.700
and the prototype chain here.

76
00:04:10.700 --> 00:04:14.890
So we should now be able to say Stephen.CalcAge,

77
00:04:17.850 --> 00:04:21.260
and, yeah, that worked.

78
00:04:21.260 --> 00:04:24.188
And so you see that we just like before,

79
00:04:24.188 --> 00:04:26.780
implemented prototypal inheritance,

80
00:04:26.780 --> 00:04:28.913
but in a completely different way.

81
00:04:29.940 --> 00:04:31.782
And now, just to make sure that we're all

82
00:04:31.782 --> 00:04:33.650
on the same page here,

83
00:04:33.650 --> 00:04:36.100
let's make sure that we really understand

84
00:04:36.100 --> 00:04:37.730
this big difference.

85
00:04:37.730 --> 00:04:40.080
And so let's take a look at a diagram

86
00:04:40.080 --> 00:04:42.223
of what's really going on here.

87
00:04:44.330 --> 00:04:45.960
So here at the right side,

88
00:04:45.960 --> 00:04:49.560
we have the way it works where de constructor functions,

89
00:04:49.560 --> 00:04:53.210
just as we have been doing it up until this point.

90
00:04:53.210 --> 00:04:55.350
So when we use the new operator

91
00:04:55.350 --> 00:04:58.180
in constructor functions or classes,

92
00:04:58.180 --> 00:05:00.800
it automatically sets the prototype

93
00:05:00.800 --> 00:05:03.430
of the instances to the constructors,

94
00:05:03.430 --> 00:05:04.803
prototype property.

95
00:05:06.350 --> 00:05:08.530
So this happens automatically.

96
00:05:08.530 --> 00:05:11.423
And so that's nothing new at this point for you.

97
00:05:12.260 --> 00:05:15.930
Now, on the other hand, with Object.create,

98
00:05:15.930 --> 00:05:19.410
we can set the prototype of objects manually

99
00:05:19.410 --> 00:05:21.920
to any object that we want.

100
00:05:21.920 --> 00:05:22.920
And in this case,

101
00:05:22.920 --> 00:05:24.760
we manually set the prototype

102
00:05:24.760 --> 00:05:29.280
of the Steven object to the person proto object.

103
00:05:29.280 --> 00:05:30.520
And that's it.

104
00:05:30.520 --> 00:05:31.780
Now the two objects

105
00:05:31.780 --> 00:05:35.190
are effectively linked through the proto property,

106
00:05:35.190 --> 00:05:37.480
just like before.

107
00:05:37.480 --> 00:05:39.270
So now looking at properties,

108
00:05:39.270 --> 00:05:41.670
or methods in a prototype chain,

109
00:05:41.670 --> 00:05:43.620
works just like it worked

110
00:05:43.620 --> 00:05:46.860
in function constructors, or classes.

111
00:05:46.860 --> 00:05:49.570
And so the prototype chain, in fact,

112
00:05:49.570 --> 00:05:51.920
looks exactly the same here.

113
00:05:51.920 --> 00:05:53.500
The big difference is

114
00:05:53.500 --> 00:05:56.004
that we didn't need any constructor function,

115
00:05:56.004 --> 00:05:59.016
and also no prototype property at all,

116
00:05:59.016 --> 00:06:02.320
to achieve the exact same thing.

117
00:06:02.320 --> 00:06:05.360
So this is actually a bit more straightforward,

118
00:06:05.360 --> 00:06:07.290
and a bit more natural.

119
00:06:07.290 --> 00:06:11.480
And I guess, that it might also be easier to understand.

120
00:06:11.480 --> 00:06:13.770
However, the reason why I'm showing you

121
00:06:13.770 --> 00:06:15.900
this Object.create technique,

122
00:06:15.900 --> 00:06:19.110
right at the end, is because in practice,

123
00:06:19.110 --> 00:06:20.350
in the real world,

124
00:06:20.350 --> 00:06:22.790
this is actually the least used way

125
00:06:22.790 --> 00:06:25.916
of implementing prototypal inheritance.

126
00:06:25.916 --> 00:06:28.490
However, it's still very important

127
00:06:28.490 --> 00:06:31.940
to know exactly how Object.create works,

128
00:06:31.940 --> 00:06:33.960
because you will still stumble upon

129
00:06:33.960 --> 00:06:36.020
this in the real world.

130
00:06:36.020 --> 00:06:37.715
And even more importantly,

131
00:06:37.715 --> 00:06:39.990
we will need Object.create

132
00:06:39.990 --> 00:06:42.436
to link prototypes in the next lecture,

133
00:06:42.436 --> 00:06:47.010
in order to implement inheritance between classes.

134
00:06:47.010 --> 00:06:50.270
So with that, we're gonna take object oriented programming

135
00:06:50.270 --> 00:06:52.100
to a whole new level.

136
00:06:52.100 --> 00:06:55.920
And the Object.create function is gonna be crucial in that,

137
00:06:55.920 --> 00:06:56.943
as we will see.

138
00:06:58.511 --> 00:07:02.930
And of course, we can now verify everything I just said,

139
00:07:02.930 --> 00:07:07.930
using CALT here. So we can do Steven.__Proto.

140
00:07:11.943 --> 00:07:14.533
And so that is now exactly the object

141
00:07:14.533 --> 00:07:16.293
that we specified up here.

142
00:07:17.360 --> 00:07:21.260
So you see, this is exactly PersonProto.

143
00:07:21.260 --> 00:07:22.683
And that makes sense,

144
00:07:23.590 --> 00:07:26.350
Because here, we said explicitly,

145
00:07:26.350 --> 00:07:28.800
that personal proto should in fact,

146
00:07:28.800 --> 00:07:30.503
be the prototype of Steven.

147
00:07:32.130 --> 00:07:34.510
And so therefore, this, of course,

148
00:07:34.510 --> 00:07:39.510
is gonna be true, and it is.

149
00:07:42.070 --> 00:07:45.189
So now that we know exactly what's going on here,

150
00:07:45.189 --> 00:07:47.633
let's quickly create another person.

151
00:07:48.710 --> 00:07:53.710
So const Sarah = Object.create.

152
00:07:57.420 --> 00:08:00.453
And once again, here, use PersonProto.

153
00:08:02.810 --> 00:08:06.150
But now, in order to set properties on this object,

154
00:08:06.150 --> 00:08:10.120
let's do it in a better way than what we did here.

155
00:08:10.120 --> 00:08:12.570
So doing this is a little bit weird.

156
00:08:12.570 --> 00:08:14.268
And it goes against the spirit

157
00:08:14.268 --> 00:08:17.520
of creating objects programmatically.

158
00:08:17.520 --> 00:08:21.020
So if we're serious about using Object.create,

159
00:08:21.020 --> 00:08:22.750
we should implement a function

160
00:08:22.750 --> 00:08:25.343
that basically does this work for us.

161
00:08:26.400 --> 00:08:29.517
So let's create a new method here.

162
00:08:29.517 --> 00:08:31.173
And this can have any name,

163
00:08:32.060 --> 00:08:33.970
so I will call it init.

164
00:08:33.970 --> 00:08:35.990
But this is going to be a little bit similar

165
00:08:35.990 --> 00:08:38.973
to the constructor, that we have in classes.

166
00:08:40.160 --> 00:08:42.780
So this one will also get a name,

167
00:08:42.780 --> 00:08:44.397
or let's say first name,

168
00:08:44.397 --> 00:08:46.563
and a birth year.

169
00:08:48.410 --> 00:08:49.980
And then just like before,

170
00:08:49.980 --> 00:08:52.960
we will use this property

171
00:08:52.960 --> 00:08:56.470
and set first name to first name,

172
00:08:56.470 --> 00:08:59.453
and then this.birth year,

173
00:09:00.310 --> 00:09:03.223
set it to birth year, as well.

174
00:09:04.120 --> 00:09:05.370
And so you see that

175
00:09:05.370 --> 00:09:08.220
this looks a bit like the constructor function

176
00:09:08.220 --> 00:09:09.713
that we created earlier.

177
00:09:11.130 --> 00:09:13.300
However, this has actually nothing

178
00:09:13.300 --> 00:09:16.370
to do with any constructor function,

179
00:09:16.370 --> 00:09:19.130
because we are not using the new operator

180
00:09:19.130 --> 00:09:24.027
to call this we will simply do Sarah.init

181
00:09:26.580 --> 00:09:29.320
and then we will pass in the arguments.

182
00:09:29.320 --> 00:09:33.553
So let's say Sarah, and 1979, for example.

183
00:09:37.010 --> 00:09:40.453
And so let's then use CalcAGe here as well.

184
00:09:42.730 --> 00:09:46.173
And so then, that just works beautifully as well.

185
00:09:47.540 --> 00:09:50.030
So here this keyword will of course,

186
00:09:50.030 --> 00:09:52.950
also points to the Sarah object now,

187
00:09:52.950 --> 00:09:57.720
but it does so because we explicitly called init on Sarah.

188
00:09:57.720 --> 00:09:59.520
So again, this has nothing to do

189
00:09:59.520 --> 00:10:03.250
with constructor functions that we saw earlier.

190
00:10:03.250 --> 00:10:04.990
And it's also completely different

191
00:10:04.990 --> 00:10:09.990
from the constructor method that we have in ESX classes.

192
00:10:10.240 --> 00:10:11.750
This is just a manual way

193
00:10:12.750 --> 00:10:15.860
of basically initializing the object.

194
00:10:15.860 --> 00:10:18.310
And this here could be any name.

195
00:10:18.310 --> 00:10:20.440
And indeed, we could have a method like

196
00:10:20.440 --> 00:10:23.053
this in any other object literal.

197
00:10:25.660 --> 00:10:30.210
So essentially, this is how Object.create works.

198
00:10:30.210 --> 00:10:32.440
So the big takeaway is

199
00:10:32.440 --> 00:10:35.670
that Object.create creates a new object,

200
00:10:35.670 --> 00:10:38.450
and the prototype of that object

201
00:10:38.450 --> 00:10:41.660
will be the object that we passed in.

202
00:10:41.660 --> 00:10:44.040
So that's what matters from this video.

203
00:10:44.040 --> 00:10:47.190
And that's very important to understand in the future,

204
00:10:47.190 --> 00:10:50.750
when we will implement true class inheritance because

205
00:10:50.750 --> 00:10:53.863
for that, we are gonna need Object.create.

