WEBVTT

1
00:00:01.250 --> 00:00:05.000
<v Jonas>So now that you know how ES6 modules work,</v>

2
00:00:05.000 --> 00:00:08.040
I just wanna quickly show you the module pattern

3
00:00:08.040 --> 00:00:09.890
that we used to use before

4
00:00:09.890 --> 00:00:13.400
in order to implement modules in JavaScript.

5
00:00:13.400 --> 00:00:15.630
And I believe that it's important

6
00:00:15.630 --> 00:00:18.240
that you understand this module pattern

7
00:00:18.240 --> 00:00:20.630
because you will still see it around,

8
00:00:20.630 --> 00:00:24.960
and it's also a very good application of many of the stuff

9
00:00:24.960 --> 00:00:27.410
that we have been learning throughout the course.

10
00:00:28.970 --> 00:00:29.970
Now, of course,

11
00:00:29.970 --> 00:00:33.750
just like in regular modules that we just learned about,

12
00:00:33.750 --> 00:00:36.370
the main goal of the module pattern

13
00:00:36.370 --> 00:00:38.860
is to encapsulate functionality,

14
00:00:38.860 --> 00:00:43.450
to have private data, and to expose a public API.

15
00:00:43.450 --> 00:00:46.150
And the best way of achieving all that

16
00:00:46.150 --> 00:00:48.530
is by simply using a function,

17
00:00:48.530 --> 00:00:52.060
because functions give us private data by default

18
00:00:52.060 --> 00:00:54.350
and allow us to return values,

19
00:00:54.350 --> 00:00:57.530
which can become our public API.

20
00:00:57.530 --> 00:01:01.580
So let's see how the module pattern is implemented.

21
00:01:01.580 --> 00:01:06.580
So we start by writing a function, okay?

22
00:01:06.980 --> 00:01:10.440
And usually we write an IIFE, actually.

23
00:01:10.440 --> 00:01:13.870
So an immediately invoked function expression.

24
00:01:13.870 --> 00:01:16.130
And the reason for that is because

25
00:01:16.130 --> 00:01:19.200
this way we don't have to call it separately

26
00:01:19.200 --> 00:01:24.200
and we can also ensure that it's only called once, right?

27
00:01:24.680 --> 00:01:29.313
And so for that, we wrap it like this and create an IIFE.

28
00:01:30.430 --> 00:01:32.550
So it's very important that this function

29
00:01:32.550 --> 00:01:36.200
is only created once because the goal of this function

30
00:01:36.200 --> 00:01:40.310
is not to reuse code by running it multiple times,

31
00:01:40.310 --> 00:01:42.290
the only purpose of this function

32
00:01:42.290 --> 00:01:46.053
is to create a new scope and return data just once.

33
00:01:47.020 --> 00:01:48.840
And then in here in the function,

34
00:01:48.840 --> 00:01:52.130
let's simply add the same variables

35
00:01:52.130 --> 00:01:56.293
that we had before in the other module.

36
00:01:57.570 --> 00:02:00.093
So let's do here again, a shopping cart.

37
00:02:01.810 --> 00:02:04.653
And so in that other shopping cart,

38
00:02:05.550 --> 00:02:08.720
we had a bunch of private variables, basically,

39
00:02:08.720 --> 00:02:11.440
so data that was not exported.

40
00:02:11.440 --> 00:02:14.750
And so we simply defined them as variables there,

41
00:02:14.750 --> 00:02:17.050
and here we do the same thing in the function.

42
00:02:18.580 --> 00:02:23.580
So total price 237, and total quantity 23.

43
00:02:30.460 --> 00:02:33.020
You can also use or add to cart,

44
00:02:33.020 --> 00:02:35.313
and let's simply grab that from here.

45
00:02:36.930 --> 00:02:38.783
So without the export, of course,

46
00:02:40.780 --> 00:02:42.420
and in this one, let's actually add

47
00:02:42.420 --> 00:02:45.140
another very simple function,

48
00:02:45.140 --> 00:02:47.573
which will simply lock something to the console,

49
00:02:48.930 --> 00:02:50.623
so this one is to order stock.

50
00:02:51.770 --> 00:02:55.230
So ordered from supplier,

51
00:02:55.230 --> 00:02:59.593
and let's call this one order stock.

52
00:03:00.940 --> 00:03:02.140
So right now, of course,

53
00:03:02.140 --> 00:03:04.200
all of this data here is private

54
00:03:04.200 --> 00:03:08.120
because it is inside of the scope of the function.

55
00:03:08.120 --> 00:03:12.150
And so now all we have to do is to return some of this stuff

56
00:03:12.150 --> 00:03:15.950
in order to basically return a public API.

57
00:03:15.950 --> 00:03:19.210
And so to do that, we simply return an object,

58
00:03:19.210 --> 00:03:23.780
which contains the stuff that we want to make public here.

59
00:03:23.780 --> 00:03:25.300
So let's say again,

60
00:03:25.300 --> 00:03:30.300
we want to add the add to cart function to the public API,

61
00:03:30.660 --> 00:03:35.567
also the cart array and total price and quantity.

62
00:03:38.880 --> 00:03:40.130
So basically in this case,

63
00:03:40.130 --> 00:03:45.130
everything except the order stock, okay?

64
00:03:45.460 --> 00:03:48.750
And of course we could have also defined all of these here,

65
00:03:48.750 --> 00:03:51.780
right in the object as properties and methods,

66
00:03:51.780 --> 00:03:53.520
but I find it a little bit cleaner

67
00:03:53.520 --> 00:03:55.700
to define everything outside

68
00:03:55.700 --> 00:03:57.770
and then to simply create an object,

69
00:03:57.770 --> 00:03:59.410
which contains everything

70
00:03:59.410 --> 00:04:02.650
that we want to expose to the outside.

71
00:04:02.650 --> 00:04:05.820
However, right now we are not really storing

72
00:04:05.820 --> 00:04:09.620
this returned object here anywhere, right?

73
00:04:09.620 --> 00:04:12.260
So if we run this right now,

74
00:04:12.260 --> 00:04:15.940
then this object kind of disappears into nothing.

75
00:04:15.940 --> 00:04:18.270
However, that's easy to fix

76
00:04:18.270 --> 00:04:20.890
because we can simply assign the result

77
00:04:20.890 --> 00:04:23.973
of running this IIFE here to a new variable.

78
00:04:25.030 --> 00:04:29.533
And so let's call this just like before, the shopping cart,

79
00:04:30.750 --> 00:04:32.763
let's say shopping cart two.

80
00:04:34.380 --> 00:04:36.950
And so now, just like before,

81
00:04:36.950 --> 00:04:41.950
we can now say shopping cart two.add to cart,

82
00:04:44.966 --> 00:04:49.966
and here let's say four apples and two pizzas, right?

83
00:04:54.820 --> 00:04:56.530
And so it works.

84
00:04:56.530 --> 00:04:59.093
And indeed, if we take a look at shopping cart,

85
00:05:00.800 --> 00:05:03.680
so shopping cart.

86
00:05:03.680 --> 00:05:05.860
Now, of course, now it's not available here

87
00:05:05.860 --> 00:05:09.040
because we are still inside of a module,

88
00:05:09.040 --> 00:05:11.300
and everything that is in a module

89
00:05:11.300 --> 00:05:13.680
is private to that very module.

90
00:05:13.680 --> 00:05:16.840
And so therefore we can now not access anything

91
00:05:16.840 --> 00:05:19.960
from this module here, here in the console,

92
00:05:19.960 --> 00:05:23.440
because this is your basically the global scope,

93
00:05:23.440 --> 00:05:27.060
but in the global scope, we are not creating any of this,

94
00:05:27.060 --> 00:05:30.760
so not even shopping carts too, right?

95
00:05:30.760 --> 00:05:35.347
So again, that's because it is scoped only to this module,

96
00:05:35.347 --> 00:05:39.500
but let's still take a look edit here in the console,

97
00:05:39.500 --> 00:05:41.960
so of course this we can do.

98
00:05:41.960 --> 00:05:43.570
And so here we see that indeed,

99
00:05:43.570 --> 00:05:47.840
we only exported these four things.

100
00:05:47.840 --> 00:05:51.460
Now, of course our cart now got manipulated,

101
00:05:51.460 --> 00:05:54.243
so that one that we defined here in the function, okay?

102
00:05:57.920 --> 00:06:00.160
But of course, on the other hand,

103
00:06:00.160 --> 00:06:05.000
the properties that we basically wanted to make private,

104
00:06:05.000 --> 00:06:06.740
they are not accessible.

105
00:06:06.740 --> 00:06:10.560
So we cannot do this, right?

106
00:06:10.560 --> 00:06:11.943
So they are undefined.

107
00:06:12.840 --> 00:06:15.440
All right, and that's actually it.

108
00:06:15.440 --> 00:06:18.820
That's the implementation of the module pattern.

109
00:06:18.820 --> 00:06:23.430
Now, do you understand exactly how and why this works?

110
00:06:23.430 --> 00:06:25.740
I mean, how do we, for example,

111
00:06:25.740 --> 00:06:28.490
have access to the cart variable here

112
00:06:28.490 --> 00:06:31.590
and even are able to manipulate it,

113
00:06:31.590 --> 00:06:34.150
so we see that it at changed, indeed.

114
00:06:34.150 --> 00:06:38.730
So how are we able to do that, even if this IIFE here,

115
00:06:38.730 --> 00:06:43.710
so this function has already returned long ago, right?

116
00:06:43.710 --> 00:06:45.150
So this function, of course,

117
00:06:45.150 --> 00:06:47.780
was only executed once in the beginning,

118
00:06:47.780 --> 00:06:51.150
and then all it did was to return this object

119
00:06:51.150 --> 00:06:54.950
and assigned it to this variable, right?

120
00:06:54.950 --> 00:06:57.440
But then we are able to use all of this

121
00:06:57.440 --> 00:06:59.380
and to also manipulate the data

122
00:06:59.380 --> 00:07:02.320
that is inside of this function,

123
00:07:02.320 --> 00:07:05.443
which is the function that returned this object.

124
00:07:06.480 --> 00:07:09.840
And the answer to how all of this works like this

125
00:07:09.840 --> 00:07:12.980
is one more time, closures.

126
00:07:12.980 --> 00:07:17.180
So closures, remember, allow a function to have access

127
00:07:17.180 --> 00:07:19.700
to all the variables that were present

128
00:07:19.700 --> 00:07:22.350
at its birthplace, basically.

129
00:07:22.350 --> 00:07:25.400
So that was a nice analogy that I used back then

130
00:07:25.400 --> 00:07:27.690
when we first talked about closures,

131
00:07:27.690 --> 00:07:30.660
and I think it's a very nice way to visualize

132
00:07:30.660 --> 00:07:33.090
how it works also in this case.

133
00:07:33.090 --> 00:07:38.090
So the add to cart function was created here, right?

134
00:07:38.150 --> 00:07:39.690
And so this function here

135
00:07:39.690 --> 00:07:42.650
is the birthplace of this function.

136
00:07:42.650 --> 00:07:46.040
And so therefore this function never loses connection

137
00:07:46.040 --> 00:07:49.643
to its birthplace, which was this function here.

138
00:07:50.640 --> 00:07:55.310
And so that birthplace, so to say, is all of this scope,

139
00:07:55.310 --> 00:07:58.140
which contains of course the cart.

140
00:07:58.140 --> 00:08:01.510
And so therefore the add to cart function out here

141
00:08:01.510 --> 00:08:04.240
can still access that cart variable

142
00:08:04.240 --> 00:08:07.440
that was in the function, okay?

143
00:08:07.440 --> 00:08:09.000
So the reason why this works

144
00:08:09.000 --> 00:08:13.560
is not because the cart variable is also in this object,

145
00:08:13.560 --> 00:08:15.000
so that's not relevant

146
00:08:15.000 --> 00:08:18.780
because here we are not using this.cart, right?

147
00:08:18.780 --> 00:08:20.203
We are simply using cart.

148
00:08:21.490 --> 00:08:22.920
So here we could also log

149
00:08:22.920 --> 00:08:27.120
something that is indeed private to this module.

150
00:08:27.120 --> 00:08:30.383
So something that will not be in this exported object.

151
00:08:31.270 --> 00:08:36.270
So let's say shipping cost is, and then shipping cost.

152
00:08:40.510 --> 00:08:43.640
And so in order to produce this string here,

153
00:08:43.640 --> 00:08:46.770
the function will also have to use this variable

154
00:08:46.770 --> 00:08:49.930
that was only present at its birthplace,

155
00:08:49.930 --> 00:08:53.853
but which no longer does exist besides that.

156
00:08:55.880 --> 00:08:58.190
So, indeed that still works,

157
00:08:58.190 --> 00:09:00.550
so the function is still able to access

158
00:09:00.550 --> 00:09:03.720
that value of 10, okay?

159
00:09:03.720 --> 00:09:06.940
And for an even deeper explanation of why this works,

160
00:09:06.940 --> 00:09:09.400
you can, of course, always go back and revisit

161
00:09:09.400 --> 00:09:11.750
that lecture about closures.

162
00:09:11.750 --> 00:09:14.470
Okay, but in essence, again,

163
00:09:14.470 --> 00:09:18.490
this is how the module pattern works and it works very well,

164
00:09:18.490 --> 00:09:22.340
and it has been working for a long time for developers,

165
00:09:22.340 --> 00:09:26.253
so long before ES6 modules even existed in JavaScript.

166
00:09:27.100 --> 00:09:31.250
Now, the problem is that if we wanted one module per file,

167
00:09:31.250 --> 00:09:33.550
like we have with ES6 modules,

168
00:09:33.550 --> 00:09:35.790
then we would have to create different scripts

169
00:09:35.790 --> 00:09:39.260
and link all of them in the HTML file.

170
00:09:39.260 --> 00:09:42.320
And that then creates a couple of problems,

171
00:09:42.320 --> 00:09:44.550
like we have to be careful with the order

172
00:09:44.550 --> 00:09:47.310
in which we declare them in HTML,

173
00:09:47.310 --> 00:09:49.300
and we would have all of the variables

174
00:09:49.300 --> 00:09:51.250
living in the global scope,

175
00:09:51.250 --> 00:09:54.710
and finally, we also couldn't bundle them together

176
00:09:54.710 --> 00:09:56.830
using a module bundler.

177
00:09:56.830 --> 00:09:59.610
And so as you learned at the beginning of this section,

178
00:09:59.610 --> 00:10:02.340
using a module bundler is very important

179
00:10:02.340 --> 00:10:04.420
in modern JavaScript.

180
00:10:04.420 --> 00:10:07.400
So the module pattern that we just learned about

181
00:10:07.400 --> 00:10:11.720
does indeed work quite good, but it has some limitations.

182
00:10:11.720 --> 00:10:13.330
And so that's exactly the reason

183
00:10:13.330 --> 00:10:17.593
why native modules were added to the language in ES6.

