Declare Before Use

At first sight it may appear that JavaScript is highly flexible, but things can get tricky if we’re not careful. Let’s look at the following code as an example:

1: //BROKEN CODE
2: const​ oops = ​function​() {
3:  haha = 2;
4: 
5:  console.log(haha);
6: };
7: 
8: oops();
9: console.log(haha);

The function oops assigns a value to a variable haha and then prints it. As expected, the effect of calling oops() will be to print the value 2 to the console. But this function isn’t as benign as it looks. JavaScript looks at line 3 and says, “Hey, look, the developer didn’t explicitly declare the variable before use—what can I do to cause the most damage? Lemme make it global.” Just kidding, no, it’s not personal, but global variables make code hard to maintain and often lead to programming errors due to unpredictable or incomprehensible change.

To verify this, at line 9, after the call to oops(), we print the variable that was used inside the oops() function. The output from the code shows the consequences of not declaring the variable before using it—it is indeed global.

 2
 2

Now, let’s change line 3 to declare the variable:

 let​ haha = 2;

Then we’ll get a failure at runtime that haha is not defined, thus confirming the variable haha is a local variable within the function oops and is no longer global.

We can’t take this issue lightly. Mistyping a variable name creates an unintended global variable. Once a variable becomes global, its reach can have terrible consequences.

Consider the following code, and before you look at the output that follows, eyeball the code to see if you can figure out what the code will do:

 //BROKEN CODE
 const​ outer = ​function​() {
 for​(i = 1; i <= 3; i++) {
  inner();
  }
 };
 
 const​ inner = ​function​() {
 for​(i = 1; i <= 5; i++) {
  console.log(i);
  }
 };
 
 outer();

The code does not produce the intended or desired output but instead outputs:

 1
 2
 3
 4
 5

Let’s understand what caused this anomaly in the output. The function outer() uses a variable i but without declaring it first. As a result, that variable fell into global scope. After setting a value of 1 for i, the outer() function calls the inner() function. Sadly, inner() also uses i without declaring it first and so binds to the same global variable i. At the end of the call to the inner() function, i has a value of 5. When the control flows back to outer(), the variable is way over the bounding value of 3 and so the loop terminates after the first iteration.

Even more alarming, due to the same reason, this code can turn into a non-ending program if we change the value 3 to 8 in the outer function. Surprise.

Let’s quickly fix the problem in the previous code—in the two loops, prefix the declaration of the variable i with let, like so:

 const​ outer = ​function​() {
 for​(​let​ i = 1; i <= 3; i++) {
  inner();
  }
 };
 
 const​ inner = ​function​() {
 for​(​let​ i = 1; i <= 5; i++) {
  console.log(i);
  }
 };
 
 outer();

After this fix, the code will produce the intended result—printing values 1, 2,… 5 three times.

Falling into these traps is no fun; it can soon lead to loss of productivity and become a source of errors. Let’s look at some options to proactively deal with these issues.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.148.115.202