Execution Context and Hoisting In JavaScript

Image of Color Guessing Game App



First Example

The code below is some of the code from the Color Guessing Challenge pictured above.

Some snippets from the code are great examples of Execution Context (The Creation and Execution Phases) and Hoisting.


var gameOver = false;
var squares = document.querySelectorAll(‘.square’);

var newRandomColors = [];

var header = document.querySelector(‘header’);
var colorDisplay = document.querySelector(‘#colorDisplay’);

colorDisplay.textContent = winningColor;

var messageDisplay = document.querySelector(‘#message’);
 
for(var i = 0; i < squares.length; i++) {
var r = Math.floor(Math.random() * 256);
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
var colorString = ‘rgb(‘ + r + ‘, ‘ + g + ‘, ‘ + b + ‘)’;
squares[i].style.backgroundColor = colorString;

newRandomColors.push(colorString);

 
squares[i].addEventListener(‘click’, function(){
var clickedColor = this.style.backgroundColor;
if(clickedColor === winningColor) {
changeColors(clickedColor);
document.body.classList.add(‘winner’);
messageDisplay.textContent = ‘Correct!’;
gameOver = true;
} else if(clickedColor !== winningColor) {
this.style.backgroundColor = ‘#232323’;
messageDisplay.textContent = ‘Try Again’;
}

});
}
 

var winningColor = newRandomColors[Math.floor(Math.random() * newRandomColors.length)];

 
function changeColors(color) {
for(var i = 0; i < squares.length; i++) {
squares[i].style.backgroundColor = winningColor;
}
header.style.backgroundColor = winningColor;
}


If the winningColor variable were defined BEFORE the for loop, then no RGB winningColor would display in the header. That’s because the random colors are added to the newRandomColors array within the for loop. So if you had this line,
 
var winningColor = newRandomColors[Math.floor(Math.random() * newRandomColors.length)];
 
before the for loop, the newRandomColors.length part would be 0, and the newRandomColors array would be empty. Therefore a winning color would not exist, and the squares and header would not change color when you win, nor does the game do anything except still do what it does when you choose an incorrect square.
 
This illustrates that before the code is executed, the Execution Context during the Creation phase will create memory space for variable declarations, not their definitions, and for function statements. Then due to Hoisting, when the code is executed during the Execution Context Execution phase, the code will have access to these values from the very first line of code, even if the location (Lexical Environment) the values are physically written in the code is all the way at the bottom.


Second Example

This version of the code is a little more organized, now using a function to pick the winning color, instead of the winningColor variable:


var gameOver = false;
var squares = document.querySelectorAll(‘.square’);
var newRandomColors = [];
var header = document.querySelector(‘header’);
var colorDisplay = document.querySelector(‘#colorDisplay’);
var messageDisplay = document.querySelector(‘#message’);
 
for(var i = 0; i < squares.length; i++) {
var r = Math.floor(Math.random() * 256);
var g = Math.floor(Math.random() * 256);
var b = Math.floor(Math.random() * 256);
var colorString = ‘rgb(‘ + r + ‘, ‘ + g + ‘, ‘ + b + ‘)’;
squares[i].style.backgroundColor = colorString;
newRandomColors.push(colorString);
 
squares[i].addEventListener(‘click’, function(){
var clickedColor = this.style.backgroundColor;
if(clickedColor === winningColor) {
changeColors(clickedColor);
document.body.classList.add(‘winner’);
messageDisplay.textContent = ‘Correct!’;
gameOver = true;
} else if(clickedColor !== winningColor) {
this.style.backgroundColor = ‘#232323’;
messageDisplay.textContent = ‘Try Again’;
}

});
}
 

var winningColor = pickColor();

colorDisplay.textContent = winningColor;

 
function changeColors(color) {
for(var i = 0; i < squares.length; i++) {
squares[i].style.backgroundColor = winningColor;
}
header.style.backgroundColor = winningColor;
}
 

function pickColor() {
var randomIndex = Math.floor(Math.random() * newRandomColors.length);
return newRandomColors[randomIndex];
}



The winningColor variable is still placed after the for loop, and now the execution of the pickColor function also placed after the for loop in this example, for the same reasons the winningColor variable was in the first example. And the execution of the function pickColor would not work when the code is executed, were it not for the Hoisting of its function statement. Because of this, pickColor() can be written before its function statement, and the function will still be executed.


Conclusion

So that about sums it up for these examples of Execution Context (Creation and Execution Phases) and Hoisting. And this also was an unintentional example of Lexical Environments. Let me know your thoughts. And of course if you have any suggestions feel free to share those too.
 
Love & Peace,
 
Danielle

Image of JavaScript passing by reference

Pass By Value vs. By Reference In JavaScript


So I’m building a little app in JavaScript and a piece of the code that I thought was simple, didn’t want to cooperate. I proceed to dig into WHY this was happening and came across one of those features of JavaScript that I felt could use a little explanation here.

JavaScript values are passed by value, not by reference.

This is one of those features of JavaScript you don’t see getting too much attention.

For example if you have an input and you then select it like so:

var input = document.querySelector(‘input’);

Plus:

var finalScore = 7;

var finalScoreDisplay = document.querySelector(‘#finalScoreDisplay’);

Then you do:

var userFinalScore = input.value;
var userFinalNumber = Number(userFinalScore);

And you also have:

input.addEventListener(‘change’, function(){
finalScore = userFinalNumber;
finalScoreDisplay.textContent = finalScore;
});

Weird things start happening when you start putting DOM (Document Object Model) representations of HTML elements, while accessing their properties, and then trying to put that into variables. They don’t seem to work anymore. It’s as if the value gets overwritten, AND/OR the variable’s not actually getting assigned the value. Or at least the value you intended to assign it.

This would be because the variable is getting assigned a reference to the location of the object, as a value. As opposed to the variable getting assigned the value of the object’s property itself.

Interesting.

By the way if you see something else going on here I might like to know about, let me know! Comment, email, smoke signal, it’s all fine. I’d appreciate it.

And now, back to coding.

Love & Peace,

Danielle

Image of the names of a lot of programming languages

Don’t Learn a Million Programming Languages

Learn one, and understand the logic. At least at first.

When I first started learning programming I used to think that learning the syntax of a couple programming languages was important. Namely JavaScript and PHP. But I came to find that I knew the syntax, but I still couldn’t program. I couldn’t make anything myself. I came to realize that learning syntax is the simple part.

In your first language build things yourself. Building applications yourself will cement the logic in your mind. Start with simple apps.

After you understand the basics of the logic in your first programming language, THEN learn another language if you really want to. Though I would recommend sticking with one for a while. Then you’re really more or less just learning the syntax of the language because you already understand the logic in most programming languages. That is if you picked a common language, not an obscure one that’s different from most.

I’ve also found that sticking to one or a few things is a great confidence boost when learning whole new concepts. It gives you a chance to gain some type of mastery over things and eventually, you start to see over the top of that learning curve.

Love & Peace,

Danielle