Why does my variable not work, but the definition does?

Viewed 62

I am running into this problem that I can't understand. I am doing an exercise that uses DOM manipulation in order to create a grid in javascript. I defined a variable, and then included that variable inside a loop. It only created one div, but it printed my console.log 16 times like I asked. So I defined the variable instead directly inside the loop, and that worked all 16 times. Can someone help me understand what concept about scope I do not seem to understand?

This works:

let gridHome = document.getElementById('grid');
let grid = function() {
    for (i = 0; i < 16; i++){
        console.log('added a div');
        let gridBlock = document.createElement('div');
        gridBlock.setAttribute('class', 'block');
        gridHome.appendChild(gridBlock);
        console.log('run it again');
    }
}
grid();

This creates only one div but runs all 16 console.logs:

let gridHome = document.getElementById('grid');
let grid = function() {
    let gridBlock = document.createElement('div')
    for (i = 0; i < 16; i++){
        console.log('added a div');
        gridBlock;
        gridBlock.setAttribute('class', 'block');
        gridHome.appendChild(gridBlock);
        console.log('run it again');
    }
}
grid();

Any help is greatly appreciated, thank you!

2 Answers

@hashbrowns94 It's not just scope thing, It's Javascript. I'll go ahead and break it down for you. The first works this way; You define gridHome. Which will holds all the div fragments created inside the loop. So every time the loop ends you stack up gridHome with the new div created INSIDE the loop and that way it goes on till the loop ends.

In the other solution, you define GridHome to holds the fragments too. But notice the GridBlock is define outside the loop and it's also define inside the loop too but this time set to undefined (N.B reference error). The one inside the loop take precedence..and it's simply undefined (usually this should give you a reference error). So in the end, only one div is appended to the GridHome which is the one define OUTSIDE the loop.

Just to mention use const instead of let as shown below.

const gridHome = document.getElementById('grid');
let grid = function() {
    for (i = 0; i < 16; i++){
        console.log('added a div');
        const gridBlock = document.createElement('div');
        gridBlock.setAttribute('class', 'block');
        gridHome.appendChild(gridBlock);
        console.log('run it again');
    }
}
grid();
.block {
  height: 10px;
  width: 100px;
  background: blue;
  margin: 5px;
}
<div id="grid">

</div>

PART TWO Try and play with this to understand what really going on..

let gridHome = document.getElementById('grid');
let grid = function() {
   let gridBlock = document.createElement('div')
    for (i = 0; i < 16; i++){
        console.log('added a div');
        //gridBlock;
        gridBlock.setAttribute('class', 'block');
        gridHome.appendChild(gridBlock);
        console.log('run it again');
    }
}
grid();
.block {
  height: 10px;
  width: 100px;
  background: blue;
  margin: 5px;
}
<div id="grid">

</div>

Regards.

let gridHome = document.getElementById('grid');
let grid = function() {
    //let gridBlock = document.createElement('div')
    for (i = 0; i < 16; i++){
        let gridBlock = document.createElement('div') // Use this line here 
        console.log('added a div');
        gridBlock.setAttribute('class', 'block');
        gridHome.appendChild(gridBlock);
        console.log('run it again');
    }
}
grid();
Related