It is an official part of the spec (though none of the engines are conforming on it yet) that `i` is recreated for each iteration (yes `items.length` times), and that moreover, it's given the value of the previous iteration's `i` at the beginning of the next iteration.

This is done specifically for the case of closures created inside loop iterations.

Consider the canonical:

```js
for (var i=0; i<10; i++) {
   setTimeout(function(){ console.log(i); },i*1000);
}
```

We all know in that case it will print out `11` for each of the 10 seconds. The normal solution is an IIFE in each loop iteration:

```js
for (var i=0; i<10; i++) {
   (function(i){
      setTimeout(function(){ console.log(i); },i*1000);
   })(i);
}
```

But, there's a specific behavior in the ES6 spec that will make it so block scoping will solve this problem without the IIFE:

```js
for (let i=0; i<10; i++) {
   setTimeout(function(){ console.log(i); },i*1000);
}
```

That will work (in a conforming ES6 implementation) only because the `i` is being re-created for each iteration, so each callback is closing over a different `i`. If `i` existed only for the loop itself, it would fail in the same way the first `var` example did.

Moreover, it's basically like this, but shorter and thus nicer:

```js
for (var i=0; i<10; i++) {
   let j = i;
   setTimeout(function(){ console.log(j); },j*1000);
}
```

There it's clear that `j` is being re-created each iteration, so the spec just says that any `let` declaration in the `for ;;` header will also behave the same way.

Cross reference from @allenwb: https://twitter.com/awbjs/status/432408227301425153