1 | # Loop closures
|
2 | A loop closure that captures a block scoped loop variable can't be transpiled only with
|
3 | variable renaming.
|
4 |
|
5 | Let's take the following example:
|
6 |
|
7 | ```javascript
|
8 | const arr = [];
|
9 | for (let x = 0; x < 10; x++) {
|
10 | let y = x;
|
11 | arr.push(function() { return y; });
|
12 | }
|
13 | ```
|
14 |
|
15 | defs with default options gives you an error:
|
16 |
|
17 | line 4: loop-variable y is captured by a loop-closure. Tried "loopClosures": "iife" in defs-config.json?
|
18 |
|
19 | This is because With ES6 semantics `y` is bound fresh per loop iteration, so each closure captures a separate
|
20 | instance of `y`, unlike if `y` would have been a `var`.
|
21 |
|
22 | You can now either choose to rewrite it manually (in usual pre-ES6 style), with an IIFE or
|
23 | bind or similar. For example:
|
24 |
|
25 | ```javascript
|
26 | for (let x = 0; x < 10; x++) {
|
27 | const arr = [];
|
28 | (function(y) {
|
29 | arr.push(function() { return y; });
|
30 | })(x);
|
31 | }
|
32 | ```
|
33 |
|
34 | And that runs just fine and defs stops complaining. Alternatively, you can ask defs to
|
35 | create the IIFE for you by adding `"loopClosures": "iife"` to your `defs-config.json`.
|
36 | Run on the original example, defs transpiles that without complaining to:
|
37 |
|
38 | ```javascript
|
39 | var arr = [];
|
40 | for (var x = 0; x < 10; x++) {(function(){
|
41 | var y = x;
|
42 | arr.push(function() { return y; });
|
43 | }).call(this);}
|
44 | ```
|
45 |
|
46 | Not all loop closures can be transpiled into IIFE's. If the loop body (which contains the
|
47 | loop closure) also contains a `return`, `yield`, `break`, `continue`, `arguments` or `var`, then
|
48 | defs will detect that and give you an error (because an IIFE would likely change
|
49 | the loop body semantics). If so either rewrite the loop body so it doesn't use any of these or
|
50 | insert an IIFE manually (knowing what you're doing).
|
51 |
|
52 | defs does not support transforming loops containing loop closures in any other way than
|
53 | with IIFE's, including try-catch statements.
|