Closures
Closures are an extension of the concept of scope. With closures, functions have access to variables that were available in the scope where the function was created. If that seems confusing, don’t worry: closures are generally best understood by example.
As shown in the Functions section, functions have access to changing variable values. The same sort of behavior exists with functions defined within loops — the function "sees" the change in the variable's value even after the function is defined, resulting in each function referencing the last value stored in the variable.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
|
Closures can be used to prevent this by creating a unique scope for each iteration — storing each unique value of the variable within its scope.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
|
Closures can also be used to resolve issues with the this
keyword, which is unique to each scope:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
|
Function.bind
Closures can be particularly useful when dealing with callbacks. However, it is often better to use Function.bind
, which will avoid any overhead associated with scope traversal.
Function.bind
is used to create a new function. When called, the new function then calls itself in the context of the supplied this
value, using a given set of arguments that will precede any arguments provided when the new function was initially called.
As bind
is a recent addition to ECMAScript 5, it may not be present in all browsers, which is something to be wary of when deciding whether to use it. However, it's possible to work around support by using this shim from MDN:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
|
One of the simplest uses of bind
is making a function that is called with a particular value for this
, regardless of how it's called. A common mistake developers make is attempting to extract a method from an object, then later calling that method and expecting it to the use the origin object as its this
. However, this can be solved by creating a bound function using the original object as demonstrated below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
|