I am learning about the new features in ES6. I have a question about let and it concerns this code:
for (let i = 0; i < 45; i++) {
var div = document.createElement('div');
div.onclick = function() {
alert("you clicked on a box #" + i);
};
document.getElementsByTagName('section')[0].appendChild(div);
}
I am confused by this code. What is happening with that div object that is declared at the start of each loop? Is that a brand new, separate object each time, somehow enclosed in the block scope of i? Or is this div object being overwritten each pass through the loop and if so, how does it maintain it's connection to the i it is given via let?
The let keyword is used to declare variables in JavaScript. The var keyword can also be used to declare variables, but the key difference between them lies in their scopes. var is function scoped while let is block scoped - we will discuss this in more detail later.
In JavaScript, let is a keyword that is used to declare a block scoped variable.
The let keyword in Angular declares a template input variable that is referenced within the template. In Angular, the micro syntax is used to configure a directive in a compact and friendly string.
The let keyword was introduced in ES6 (2015). Variables defined with let cannot be Redeclared. Variables defined with let must be Declared before use. Variables defined with let have Block Scope.
When I like to get a better understanding of what's happening in ES6 code, I enter my Javascript into the BabelJS REPL.
Your code when entered into the REPL outputs:
'use strict';
var _loop = function (i) {
div = document.createElement('div');
div.onclick = function () {
alert("you clicked on a box #" + i);
};
document.getElementsByTagName('section')[0].appendChild(div);
};
for (var i = 0; i < 45; i++) {
var div;
_loop(i);
};
Because you used let
to assign i
, its value is only available in the scope of the loop (or the function in the Babel example) for each loop iteration. To get the same functionality for the div
variable, you could assign that variable in the loop body.
for (let div, i = 0; i < 45; i++) {
div = document.createElement('div');
...
}
Lastly, about closures and holding on to the i
variable, you're one step away from creating a closure to maintain the current i
value for each div
.
// Create a function to hold on to a specific number
function createOnClick(index) {
return function() {
alert("you clicked on a box #", index);
};
};
// Assign the function to the element's action
div.onClick = createOnClick(i);
Without the function factory, the onClick
value would always get the maximum i
value of 44. This is because the function is being run after the entire loop has iterated and i
has stopped at i < 45
.
The <div>
is a brand new object in each iteration, but it isn't enclosed in the block scope of i
.
The function expression that is attached to the div
is however also a brand new object, but this object is closing over i
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With