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.

