1
00:00:02,140 --> 00:00:09,450
So that are factory functions and closely related to factory functions is the concept of closures.

2
00:00:09,560 --> 00:00:16,210
Now here's an important rule which you can memorize for Javascript interviews, every function in Javascript

3
00:00:16,570 --> 00:00:17,980
is a closure,

4
00:00:17,980 --> 00:00:19,740
so why is every function a closure

5
00:00:19,750 --> 00:00:22,990
then? What is that concept of being a closure then?

6
00:00:22,990 --> 00:00:29,440
Well this is closely related to the idea of having scopes for our variables. As you learned earlier in

7
00:00:29,440 --> 00:00:30,670
the course,

8
00:00:30,670 --> 00:00:35,590
you have different scopes - you have block scope when we're working with variables that are created with

9
00:00:35,590 --> 00:00:41,770
const or let and that simply means that inside of curly braces like for example here in a function

10
00:00:41,770 --> 00:00:48,400
definition, if you create a variable in there or if you get a parameter, it's only usable inside of that

11
00:00:48,400 --> 00:00:50,310
function but not outside of it.

12
00:00:50,350 --> 00:00:56,500
On the other hand, global variables or constants which are created outside of functions can be used

13
00:00:56,580 --> 00:00:57,690
inside of the functions,

14
00:00:57,700 --> 00:00:59,640
that's something you already knew.

15
00:00:59,650 --> 00:01:05,590
Now if you have a function in a function, that inner function can use all the variables or parameters

16
00:01:05,590 --> 00:01:09,980
of the outer function and all variables that are defined globally,

17
00:01:10,300 --> 00:01:16,370
the outer function can not access the inner functions specific constants or variables.

18
00:01:16,390 --> 00:01:21,670
So for example here, amount could not be accessed from inside that outer function, only from inside

19
00:01:21,670 --> 00:01:22,720
that inner function,

20
00:01:22,740 --> 00:01:24,340
so that's what you already knew.

21
00:01:24,370 --> 00:01:31,300
The more technical term for this would be that we have different lexical environments. Each function

22
00:01:31,300 --> 00:01:35,420
has its own lexical environment and you have a global environment as well

23
00:01:35,500 --> 00:01:41,620
and the variables and constants are registered in these different environments you could say. Now when

24
00:01:41,620 --> 00:01:47,500
a function is created as we do it here with the function keyword by using this function declaration,

25
00:01:47,950 --> 00:01:56,740
then this function creates a new lexical environment and registers any variables it has access to inside

26
00:01:56,740 --> 00:01:57,820
of this environment.

27
00:01:57,820 --> 00:02:03,610
So in this case for the outer function, the create tax calculator function, the tax parameter here for

28
00:02:03,610 --> 00:02:10,810
example would be a variable of its lexical environment. The global environment would have the hobbies

29
00:02:10,810 --> 00:02:18,430
constant for example. The inner function has its own environment with the amount parameter but it also

30
00:02:18,430 --> 00:02:22,370
has access to the outer functions environment.

31
00:02:22,390 --> 00:02:29,020
Now when we call create tax calculator, then this inner function is created, not before we do so because

32
00:02:29,020 --> 00:02:31,740
it's inside of that creates tax calculator function,

33
00:02:31,810 --> 00:02:37,150
so where this function the outer function is created when the script parses this file, the inner function

34
00:02:37,150 --> 00:02:42,490
is only created when we call this function, when we call the create tax calculator function.

35
00:02:43,360 --> 00:02:50,200
So when this function then is created in here, something interesting happens, it's in this case here logs

36
00:02:50,260 --> 00:02:55,640
in the value for tax when this outer function runs.

37
00:02:55,690 --> 00:03:02,170
So if you then call that outer function again with a different value, since we execute a brand new function,

38
00:03:02,650 --> 00:03:09,310
since we have a totally different function execution, the inner function receives this brand new

39
00:03:09,460 --> 00:03:14,750
tax value and is totally detached from that other function execution.

40
00:03:14,920 --> 00:03:21,580
Now on the other hand if we have some other variable, let's say a multiplier for whatever reason we need

41
00:03:21,580 --> 00:03:27,460
that, 1.1 and we refer to that inside of that function no matter if it's the outer or the inner

42
00:03:27,470 --> 00:03:32,240
one, then this will be updated when it changes outside of this function.

43
00:03:32,260 --> 00:03:39,490
So for example if I multiply this with multiplier here and I then call the create tax calculator function

44
00:03:40,000 --> 00:03:42,490
and thereafter change the multiplier,

45
00:03:42,490 --> 00:03:49,240
so after calling this outer function but before calling the inner function to 1.2, you will see that

46
00:03:49,240 --> 00:03:52,960
a multiplier of 1.2 will be used, to make it easier to see,

47
00:03:53,020 --> 00:03:58,960
I'll print the multiplier here. So let's save that and reload and you see 1.2 gets printed

48
00:03:58,960 --> 00:03:59,470
here.

49
00:03:59,500 --> 00:04:01,440
So what does this tell us?

50
00:04:01,540 --> 00:04:08,740
It tells us that we do log in tax here because that's part of this specific environment of the outer

51
00:04:08,740 --> 00:04:09,370
function

52
00:04:09,370 --> 00:04:16,180
when it runs but we don't log in the concrete value of multiplier because that's part of the global

53
00:04:16,180 --> 00:04:17,010
environment

54
00:04:17,170 --> 00:04:24,970
and in the end what happens is just each function registers its surrounding environments and the variables

55
00:04:24,970 --> 00:04:26,400
that are defined in there

56
00:04:26,500 --> 00:04:33,960
and if these variables change and this function uses such a variable, then it takes the latest value.

57
00:04:34,270 --> 00:04:38,040
Now for tax in this case here, that would be the case too

58
00:04:38,050 --> 00:04:43,240
but when this inner function is created, it has a look at its surrounding environment which is this functions,

59
00:04:43,480 --> 00:04:46,690
the create tax calculator functions environment for example

60
00:04:46,840 --> 00:04:49,600
and there we have a tax variable, a tax parameter

61
00:04:49,600 --> 00:04:55,690
and if that would change, the inner function would take the new one but this never changes because the

62
00:04:55,690 --> 00:04:59,660
only time we pass in a new value is when we execute this function again,

63
00:04:59,680 --> 00:05:05,380
this however will be a brand new execution and not change that inner function that was created on the

64
00:05:05,380 --> 00:05:12,100
first function execution here, which is why that inner function created by that first function execution

65
00:05:12,400 --> 00:05:19,850
still has its old environment with the tax you set up here as an argument. Now why is it called a closure

66
00:05:19,850 --> 00:05:20,330
then?

67
00:05:20,360 --> 00:05:28,130
Because every function closes over the surrounding environment which means it registers the surrounding

68
00:05:28,130 --> 00:05:34,850
environment and the variables registered there and it memorizes the values of these variables.

69
00:05:34,850 --> 00:05:39,740
If you then change a variable, well that is reflected inside of the function

70
00:05:39,890 --> 00:05:46,040
but if it does not change, the function still is able to use for example the tax value you passed

71
00:05:46,040 --> 00:05:48,420
in when you created the outer function.

72
00:05:48,560 --> 00:05:53,210
That is not something you should take for granted because you could also read this code here in a different

73
00:05:53,210 --> 00:05:53,920
way.

74
00:05:53,990 --> 00:05:59,550
You could say when the outer function, when create tax calculator is called with a value of .19,

75
00:06:00,050 --> 00:06:05,750
then what happens is that this function runs, a new function is created which for the moment is simply

76
00:06:05,750 --> 00:06:08,040
a task that is done pretty fast

77
00:06:08,210 --> 00:06:15,890
and then we return this created function. So you could say that theoretically tax isn't used anymore,

78
00:06:15,890 --> 00:06:16,530
sure

79
00:06:16,540 --> 00:06:23,330
the inner function uses it but Javascript could just ignore that. The outer function is done and it was

80
00:06:23,330 --> 00:06:29,540
the outer function which received the tax parameter, so we could think that Javascript just gets rid

81
00:06:29,540 --> 00:06:32,030
of that tax value and ignores it

82
00:06:32,030 --> 00:06:38,060
and if we then eventually call the inner function, that might be missing. Now in Javascript, you can indeed

83
00:06:38,090 --> 00:06:41,030
take for granted that it will not be missing

84
00:06:41,120 --> 00:06:46,650
but I want to emphasize that this is not something you can take for granted in all programming languages.

85
00:06:46,760 --> 00:06:51,410
It is like this in Javascript but it's not necessarily like this in other languages.

86
00:06:51,950 --> 00:06:59,120
So a function, every function in Javascript is a closure because it closes over the variables defined in

87
00:06:59,120 --> 00:07:00,290
its environment

88
00:07:00,290 --> 00:07:06,920
and it kind of memorizes them, so that they're not thrown away when you don't need them in the surrounding

89
00:07:06,920 --> 00:07:08,380
context anymore.

90
00:07:08,420 --> 00:07:15,380
So even if multiplier wouldn't be used down there and therefore in the global context, it actually wouldn't

91
00:07:15,380 --> 00:07:16,640
be used anymore,

92
00:07:16,670 --> 00:07:22,610
Javascript will still not throw away the value stored in here because in this inner function, we still

93
00:07:22,730 --> 00:07:29,420
might use it and therefore this inner function closed over the surrounding variables and stored their

94
00:07:29,420 --> 00:07:34,280
values, so that even if you don't need them anywhere else, you can still use them from inside of the

95
00:07:34,280 --> 00:07:35,030
function.

96
00:07:35,030 --> 00:07:41,360
This is why we also call this a closure and why every function in Javascript is a closure because every

97
00:07:41,360 --> 00:07:43,570
function in Javascript behaves like this.
