WEBVTT

1
00:00:01.310 --> 00:00:03.400
<v ->Let's now talk about a feature</v>

2
00:00:03.400 --> 00:00:07.360
that is actually common to all objects in JavaScript,

3
00:00:07.360 --> 00:00:09.833
and that's getters and setters.

4
00:00:11.800 --> 00:00:14.090
So every object in JavaScript

5
00:00:14.090 --> 00:00:17.430
can have setter and getter properties.

6
00:00:17.430 --> 00:00:21.670
And we call these special properties assessor properties,

7
00:00:21.670 --> 00:00:26.430
while the more normal properties are called data properties.

8
00:00:26.430 --> 00:00:29.930
So getters and setters are basically functions

9
00:00:29.930 --> 00:00:34.930
that get and set a value so just as the name says,

10
00:00:35.090 --> 00:00:39.270
but on the outside they still look like regular properties.

11
00:00:39.270 --> 00:00:42.690
And so let's first take a look at getters and setters

12
00:00:42.690 --> 00:00:45.090
in a simple object literal,

13
00:00:45.090 --> 00:00:48.210
and for that I'm gonna use the bank account example

14
00:00:48.210 --> 00:00:50.713
from the Bankist application.

15
00:00:54.310 --> 00:00:56.723
So very simple object literal here.

16
00:00:58.170 --> 00:01:01.653
The owner is Jonas.

17
00:01:05.040 --> 00:01:06.633
Then some simple movements.

18
00:01:09.390 --> 00:01:12.983
So the values here don't really matter, okay?

19
00:01:14.720 --> 00:01:18.313
Oh, and of course I'm writing this object all wrong.

20
00:01:20.050 --> 00:01:22.603
Maybe you have already been noticing that.

21
00:01:24.360 --> 00:01:27.120
Okay, but now it should be correct.

22
00:01:27.120 --> 00:01:31.483
All right, but now to add a getter to this object.

23
00:01:32.530 --> 00:01:36.910
We can start by basically writing a normal method.

24
00:01:36.910 --> 00:01:39.220
So let's say that we want a method

25
00:01:39.220 --> 00:01:43.633
to get the latest movement and so let's call it latest.

26
00:01:44.700 --> 00:01:47.790
And then to transform this into a getter

27
00:01:47.790 --> 00:01:51.113
we simply prepend the keyword get.

28
00:01:52.390 --> 00:01:56.230
All right, and so let's simply return the last movement here

29
00:01:57.070 --> 00:02:01.483
so that's this.movements.slice -1.

30
00:02:03.220 --> 00:02:06.160
But this is actually gonna return an array,

31
00:02:06.160 --> 00:02:08.810
so an array with the last position

32
00:02:08.810 --> 00:02:13.033
and so we can simply take that out using the pop method.

33
00:02:13.930 --> 00:02:16.660
And we could've used destructuring as well,

34
00:02:16.660 --> 00:02:18.450
but I didn't want to save this

35
00:02:18.450 --> 00:02:20.493
into an external variable first.

36
00:02:21.620 --> 00:02:26.003
And so now we can use this getter like this.

37
00:02:26.890 --> 00:02:31.670
So account and then we say latest,

38
00:02:31.670 --> 00:02:34.440
but we simply use it as a property.

39
00:02:34.440 --> 00:02:37.070
All right, so we don't call the method,

40
00:02:37.070 --> 00:02:40.853
but instead we write it as if it was just a property.

41
00:02:41.930 --> 00:02:45.863
So let's see, and indeed that returns 300.

42
00:02:47.210 --> 00:02:49.120
So this can be very useful

43
00:02:49.120 --> 00:02:51.810
when we want to read something as a property,

44
00:02:51.810 --> 00:02:55.050
but still need to do some calculations before.

45
00:02:55.050 --> 00:02:59.253
Okay, and now we can do the same also as a setter.

46
00:03:00.740 --> 00:03:04.020
So we say set, latest again

47
00:03:05.430 --> 00:03:09.090
and then here we can basically add a new movement

48
00:03:09.090 --> 00:03:09.953
to the array.

49
00:03:10.840 --> 00:03:15.610
And any setter method needs to have exactly one parameter.

50
00:03:15.610 --> 00:03:17.963
So in this case that's simply a movement.

51
00:03:19.270 --> 00:03:24.270
So let's say this.movements.push

52
00:03:24.550 --> 00:03:27.463
and then that movement that we just passed into.

53
00:03:28.380 --> 00:03:31.640
Now it is not mandatory to specify a setter

54
00:03:31.640 --> 00:03:34.840
when we have a getter for the same property.

55
00:03:34.840 --> 00:03:39.620
Okay, so just a getter or just a setter would be enough.

56
00:03:39.620 --> 00:03:42.770
And so, how do we use the setter now?

57
00:03:42.770 --> 00:03:47.460
So if it was a regular method then we would have to do this.

58
00:03:47.460 --> 00:03:52.220
So account.latest and then call it with the movement,

59
00:03:52.220 --> 00:03:54.070
let's say 50.

60
00:03:54.070 --> 00:03:58.510
But now this is actually like a property and not a method.

61
00:03:58.510 --> 00:04:00.660
And so we can simply set it

62
00:04:00.660 --> 00:04:02.853
just like we set any other property.

63
00:04:03.740 --> 00:04:06.283
So we essentially set it equal to 50.

64
00:04:07.660 --> 00:04:11.380
And so now if we take a look at the movements here,

65
00:04:11.380 --> 00:04:14.150
it will then give us the complete array

66
00:04:14.150 --> 00:04:15.983
with the 50 there at the end.

67
00:04:17.660 --> 00:04:21.560
And so in a nutshell this is how getters and setters work

68
00:04:21.560 --> 00:04:25.410
for any regular object in JavaScript.

69
00:04:25.410 --> 00:04:30.020
Now however, classes do also have getters and setters,

70
00:04:30.020 --> 00:04:33.350
and they do indeed work in the exact same way.

71
00:04:33.350 --> 00:04:38.043
And so let's try them out now here in our person class.

72
00:04:39.440 --> 00:04:42.550
So here we can for example add a getter

73
00:04:42.550 --> 00:04:44.630
for the age property.

74
00:04:44.630 --> 00:04:49.630
So we can say get age and then we return the age.

75
00:04:52.530 --> 00:04:56.263
So this is of course very similar to the calcAge method

76
00:04:56.263 --> 00:04:59.920
that we already have here but that doesn't matter

77
00:04:59.920 --> 00:05:04.033
because this is really just a demonstration example.

78
00:05:06.420 --> 00:05:09.371
All right, and so like this we will be able

79
00:05:09.371 --> 00:05:14.371
to basically read the age of any object using a property.

80
00:05:15.950 --> 00:05:20.817
So let's try that here for example, jessica.age,

81
00:05:22.570 --> 00:05:26.463
and this time we actually need to log it to the console.

82
00:05:27.810 --> 00:05:30.503
And you see here we now get the same value.

83
00:05:31.470 --> 00:05:35.465
All right, so you see that the getter is indeed

84
00:05:35.465 --> 00:05:38.183
just like any other regular method

85
00:05:38.183 --> 00:05:41.010
that we set on the prototype.

86
00:05:41.010 --> 00:05:44.963
And in fact we can also check that out here.

87
00:05:46.210 --> 00:05:49.490
So if we take a look at the prototype of Jessica,

88
00:05:49.490 --> 00:05:51.750
it will be right there.

89
00:05:51.750 --> 00:05:53.260
Now it has these dots here

90
00:05:53.260 --> 00:05:56.663
because it's only calculated once we actually click this.

91
00:05:58.620 --> 00:05:59.920
Okay?

92
00:05:59.920 --> 00:06:04.920
So here too it already looks as if it would be a property

93
00:06:05.140 --> 00:06:06.750
and not a method.

94
00:06:06.750 --> 00:06:09.060
We still have the get method down here,

95
00:06:09.060 --> 00:06:12.053
but then it's also kind of ended as a property.

96
00:06:14.260 --> 00:06:15.093
All right?

97
00:06:16.510 --> 00:06:20.280
So that's a very simple use case of a getter,

98
00:06:20.280 --> 00:06:23.850
but setters and getters can actually be very useful

99
00:06:23.850 --> 00:06:27.120
for data validation and as an example,

100
00:06:27.120 --> 00:06:29.783
let's try some validation with the name.

101
00:06:30.700 --> 00:06:34.476
So for that I will actually change a firstName here

102
00:06:34.476 --> 00:06:35.476
to fullName.

103
00:06:38.210 --> 00:06:40.780
And so now here we expect a full name.

104
00:06:40.780 --> 00:06:44.053
So a name which basically contains a space.

105
00:06:45.290 --> 00:06:47.560
So let's say Jessica Davis here,

106
00:06:47.560 --> 00:06:51.830
and so now we can create a setter for the fullName property

107
00:06:51.830 --> 00:06:55.163
which will check if this is actually a full name.

108
00:06:56.340 --> 00:07:00.233
All right, so set fullName,

109
00:07:01.520 --> 00:07:03.283
and then we need the name itself,

110
00:07:04.680 --> 00:07:07.160
and then here we need some logic.

111
00:07:07.160 --> 00:07:09.663
So to test if it contains a space,

112
00:07:10.620 --> 00:07:13.843
if the name includes a space,

113
00:07:15.050 --> 00:07:17.600
and I'm not sure if it is called includes actually.

114
00:07:19.330 --> 00:07:21.330
Now let me just test it here very quick.

115
00:07:27.210 --> 00:07:30.073
Okay, we have to comment out this part.

116
00:07:35.960 --> 00:07:39.000
All right, so this method actually does exist.

117
00:07:39.000 --> 00:07:42.570
So I wasn't sure if it only exists on erase,

118
00:07:42.570 --> 00:07:45.223
but indeed it also exists on strings.

119
00:07:46.810 --> 00:07:50.550
And so in this case then we actually want to set

120
00:07:50.550 --> 00:07:55.550
this.fullName to the name that was received.

121
00:07:57.210 --> 00:07:59.953
But if not, we want to give an alert.

122
00:08:03.030 --> 00:08:08.030
So the given name is not a full name.

123
00:08:10.610 --> 00:08:14.350
So in this case what's really important to understand

124
00:08:14.350 --> 00:08:17.910
is that we are creating a setter for a property name

125
00:08:17.910 --> 00:08:19.603
that does already exist.

126
00:08:20.480 --> 00:08:23.073
So fullName is already a property

127
00:08:23.073 --> 00:08:25.100
that are trying to set here,

128
00:08:25.100 --> 00:08:27.130
but then we also have the setter.

129
00:08:27.130 --> 00:08:29.220
And so now what's gonna happen is

130
00:08:29.220 --> 00:08:32.010
that each time this code here is executed,

131
00:08:32.010 --> 00:08:35.430
so whenever we set the fullName on the this keyword,

132
00:08:35.430 --> 00:08:38.010
then actually this method here,

133
00:08:38.010 --> 00:08:41.460
so this setter is gonna be executed.

134
00:08:41.460 --> 00:08:44.630
And so that name that we pass in as fullName

135
00:08:44.630 --> 00:08:48.030
will then become this name.

136
00:08:48.030 --> 00:08:50.860
All right, let's check that out actually.

137
00:08:50.860 --> 00:08:53.910
And so now as we create Jessica here,

138
00:08:53.910 --> 00:08:58.910
you will see and indeed it, we saw Jessica Davis here,

139
00:08:59.700 --> 00:09:03.310
but now we got this crazy error here

140
00:09:03.310 --> 00:09:06.620
of maximum call stack size exceeded.

141
00:09:06.620 --> 00:09:09.420
Now that's a very cryptic error message,

142
00:09:09.420 --> 00:09:12.810
but what happens here is that there is a conflict.

143
00:09:12.810 --> 00:09:15.240
So right now both the setter function

144
00:09:15.240 --> 00:09:17.670
and this constructor function

145
00:09:17.670 --> 00:09:21.020
are trying to set the exact same property name.

146
00:09:21.020 --> 00:09:24.663
And so that gives origin to this weird error.

147
00:09:25.520 --> 00:09:27.350
So what we need to do instead

148
00:09:27.350 --> 00:09:30.330
is to here create a new property name.

149
00:09:30.330 --> 00:09:32.890
And the convention for doing that,

150
00:09:32.890 --> 00:09:36.620
so when we have a setter which is trying to set a property

151
00:09:36.620 --> 00:09:38.710
that does already exist,

152
00:09:38.710 --> 00:09:42.310
then here as a convention we add an underscore.

153
00:09:42.310 --> 00:09:45.360
So again, this is just a convention,

154
00:09:45.360 --> 00:09:47.540
it's not a JavaScript feature.

155
00:09:47.540 --> 00:09:50.120
So it's really just a different variable name

156
00:09:50.120 --> 00:09:52.940
to avoid that naming conflict.

157
00:09:52.940 --> 00:09:55.110
However, now when we do this,

158
00:09:55.110 --> 00:09:58.320
we are actually creating a new variable,

159
00:09:58.320 --> 00:10:00.700
so a fullName variable.

160
00:10:00.700 --> 00:10:02.603
So let's try this now actually.

161
00:10:04.780 --> 00:10:09.610
So if we try to look at Jessica Davis you see that right now

162
00:10:09.610 --> 00:10:13.023
the property that exists is underscore fullName.

163
00:10:14.000 --> 00:10:17.590
And so right now we cannot do jessica.fullName

164
00:10:19.600 --> 00:10:22.260
because that simply doesn't exist.

165
00:10:22.260 --> 00:10:26.120
And so to fix this we now also need to create a getter

166
00:10:26.120 --> 00:10:27.823
for the fullName property.

167
00:10:29.230 --> 00:10:32.953
And so that will simply return the underscore fullName.

168
00:10:34.610 --> 00:10:35.633
So let's see.

169
00:10:39.090 --> 00:10:41.537
So return this._fullName.

170
00:10:45.050 --> 00:10:47.620
And so if we try to do the same now,

171
00:10:47.620 --> 00:10:51.523
then you see that we are back to having this fullName here.

172
00:10:54.190 --> 00:10:55.510
All right?

173
00:10:55.510 --> 00:10:58.490
And of course, the actual property that is here

174
00:10:58.490 --> 00:11:01.380
is now still underscore fullName,

175
00:11:01.380 --> 00:11:06.380
because well that's what we do here in the setter, right?

176
00:11:06.560 --> 00:11:09.520
But then we can also compute this full name

177
00:11:09.520 --> 00:11:11.583
just as we can compute the age.

178
00:11:13.330 --> 00:11:16.450
So this pattern here is important to understand

179
00:11:16.450 --> 00:11:21.450
whenever we try to set a property that already exists.

180
00:11:24.910 --> 00:11:29.910
Now let's try another name here just to see what happens,

181
00:11:32.210 --> 00:11:33.673
and actually after all this.

182
00:11:36.830 --> 00:11:39.713
So let's create a Walter object here.

183
00:11:41.600 --> 00:11:46.143
New PersonCl, that's right.

184
00:11:47.150 --> 00:11:51.090
And now we're just using a name with one word,

185
00:11:51.090 --> 00:11:55.800
let's say 1965 and so now we get this error.

186
00:11:55.800 --> 00:11:58.163
So Walter is not a full name,

187
00:11:59.210 --> 00:12:02.010
and so right now if we check out Walter,

188
00:12:02.010 --> 00:12:06.930
age probably doesn't have any name, and yeah it doesn't.

189
00:12:06.930 --> 00:12:09.350
So just the birth year now.

190
00:12:09.350 --> 00:12:11.823
But if we then put it as a full name,

191
00:12:12.890 --> 00:12:17.890
so Walter White then indeed, Walter like this,

192
00:12:18.230 --> 00:12:20.770
then we get the underscore fullName.

193
00:12:20.770 --> 00:12:24.710
But just like before we can then also access walter.fullName

194
00:12:25.820 --> 00:12:30.350
because of that setter or actually of that getter

195
00:12:30.350 --> 00:12:32.830
that we just defined earlier.

196
00:12:32.830 --> 00:12:37.830
Now okay, great, so this is another nice feature of classes

197
00:12:38.350 --> 00:12:41.000
that can be very useful sometimes.

198
00:12:41.000 --> 00:12:44.330
Now we don't need to use getters or setters,

199
00:12:44.330 --> 00:12:46.340
and many people actually don't,

200
00:12:46.340 --> 00:12:50.170
but yeah, as I just said sometimes it's just nice

201
00:12:50.170 --> 00:12:52.370
to be able to use these features

202
00:12:52.370 --> 00:12:57.270
and especially when we need like a validation like this

203
00:12:57.270 --> 00:13:00.360
by the time we are creating a new object.

204
00:13:00.360 --> 00:13:04.230
So that's essentially what this setter here does.

205
00:13:04.230 --> 00:13:05.063
Next up,

206
00:13:05.063 --> 00:13:08.340
we're gonna take a look at yet another feature of classes,

207
00:13:08.340 --> 00:13:10.540
which is static methods.

208
00:13:10.540 --> 00:13:12.673
So let's check that out right now.

