×
Community Blog JavaScript Variables, Scope, and Hoisting

JavaScript Variables, Scope, and Hoisting

This tutorial seeks to examine the differences between var, let, and const and also the way to declare them, name and define what exactly they are.

By Alex Mungai Muchiri, Alibaba Cloud Tech Share Author. Tech Share is Alibaba Cloud's incentive program to encourage the sharing of technical knowledge and best practices within the cloud community.

It is mandatory to understand the concept of variables if you are seeking to learn any programming language. In fact, it is recommended that newbies emphasis on this one aspect to grasp the basics of coding. JavaScript variables have wide-ranging properties as well as rules governing their naming. In particular, var, let, and const are the three keywords to be used in declaring JavaScript variables. The anticipated interpretation of the variable will depend on how these keywords are used. This tutorial seeks to examine the differences between var, let, and const and also the way to declare them, name and define what exactly they are. The other thing covered in this tutorial are hoisting impacts, local and global scope effects on how variables behave.

What Are Variables?

In simple terms, variables are containers that store values. For instance, if we want to store some information that we refer to several times, we could store it in a variable to access it later or modify it. We could store a number, string, or object, or any other data types in JavaScript variable containers. Modern JavaScript is based on the ECMAScript 2015 (ES6) language specification, which expanded variable declarations from the var keyword that was the only one available initially. That is why you will only find the var in older learning resources. In this tutorial, we have dedicated an entire section to explore the differences between var, let, and const keywords below. We shall use just one type o define the variable concept by declaring it and then assigning a value to it:

// Assign the string value Sam to the username identifier
var username = "sam_shark";

Our statement constitutes a number of terms:

  1. The var keyword has been used to declare a variable
  2. The username is our variable identifier or variable name
  3. The = syntax represents an assignment operation for our statement
  4. The value in our case is "sam_shark"

We can now proceed to have username implemented in our JavaScript Code and it will remember that it is a representation of sam_shark, a string value.

// Check if variable is equal to value
if (username === "sam_shark") {
  console.log(true);
}
Output
true

As we have already mentioned, we can represent all JavaScript data types using variables. Let us now proceed to experiment with string, number, object, Boolean, and null values in our next variable declaration:

// Assignment of various variables
var name = "Sam";
var warriors = 300;
var kingdoms = [ "mammals", "birds", "amphibian" ];
var poem = { roses: "red", bananas: "green" }; 
var success = true;
var nothing = null;

We can inspect what value each variable contains using the console.log.

// Send warriors variable to the console
console.log(warriors);
Output
300

Since data contained in variables is stored in the memory, it can be accessed and modified later. We can also assign new values to variables. We shall look at a new example below that has a stored password in the variable and also how to change the password.

// Assign value to password variable
var password = "pass1";

// Reassign variable value with a new value
password = "pass2";

console.log(password);
Output
'pass2'

It is unlikely that we would store a password in the manner above as it would rather be stored in a secure database. However, the example demonstrates the way we could update values contained in variables. Initially, the value assigned to password was pass1, which we later updated to pass2. JavaScript henceforth recognizes the new value after the update.

How to Name Variables

In JavaScript, variable names are also referred to as identifiers. However, you need to have the following rules in mind when you are naming variables:

  1. The composition of variable names can only be letters (a-z), numbers (0-9), dollar sign symbols ($), or underscores (_)
  2. You may include whitespace characters (tabs or spaces) in variable names
  3. The names of variables cannot begin with numbers
  4. You cannot use any of the reserved keywords as variable names
  5. Variable names are case sensitive

When JavaScript variables and functions are declared with var or let it is conventional to name them in camel case (sometimes stylized as camelCase). To expound, the practice involves having the first word in lower case then having the first letter of all subsequent words capitalized without spacing them. In fact, this is a convention that is followed by nearly all non-constant variables with only a few exemptions. Constants are declared with the const keyword, and their names are usually written in upper case. If you are just getting started, you may find that these rules are quite a lot to learn, but don't worry, they will become second nature in no time.

Differentiating var, let, and const

As mentioned earlier, the three keywords are the only way to define JavaScript variables. Their use-cases are three-pronged, scope, hoisting and reassignment as described by the rable below:

1

If you are wondering which of these constants to use when writing your own programs, then you should know this: the common practice is to use const as much as you can. In the case of in the case of loops and reassignment, let is mostly preferred. In most cases, you only use var when working on legacy code.

Understanding Scope

When defining the current context of code, we use scope as the metric. It is a measure of variable accessibility in JavaScript. Scope id of two types: local and global:

  1. We define scope as Global when variables outside of a block
  2. The scope is Local when variables are inside of a block

Let us start by creating a global variable in the example below:

// Initialize a global variable
var creature = "fox";

We have previously seen that it is possible to reassign variables. It is even possible to create new variables named as variables in outer scopes using a local scope and we do not have to change or reassign the initial value.

Accordingly, we have an example in the below that we have created a global species variable. Now, let us send it to the console and we shall be able to see a variable's value depends on the scope. The original values do not change:

// Initialize a global variable
var species = "man";

function transform() {
  // Initialize a local, function-scoped variable
  var species = "cat";
  console.log(species);
}

// Log the global and local variable
console.log(species);
transform();
console.log(species);
Output
man
cat
man

We have seen a function-scoped variable as the local variable in our example. When we declare variables with the var keyword, they tend to be function-scoped. In other words, the functions they recognize are of a different scope. However, variables declared with let and const tend to be block-scoped. Therefore, each time we use if statements, and for and while loops, we create new local scopes for all block types, and that includes functional blocks.

Let us differentiate between function- and block-scoped variables in an if block using let.

var fullMoon = true;

// Initialize a global variable
let species = "man";

if (fullMoon) {
  // Initialize a block-scoped variable
  let species = "cat";
  console.log(`It is a full moon. Presley is currently a ${species}.`);
}

console.log(`It is not a full moon. Presley is currently a ${species}.`);
Output
It is a full moon. Presley is currently a cat.
It is not a full moon. Presley is currently a man.

We have shown in the above example that the species variable has two values: the global value (man) and the local value (cat). Using var, however, yields a different result as shown below:

// Use var to initialize a variable
var species = "man";

if (fullMoon) {
  // Attempt to create a new variable in a block
  var species = "cat";
  console.log(`It is a full moon. Presley is currently a ${species}.`);
}

console.log(`It is not a full moon. Presley is currently a ${species}.`);
Output
It is a full moon. Presley is currently a cat.
It is not a full moon. Presley is currently a cat.

The output is the same value for both the global variable and the block-scoped variable, cat. The reason for this phenomenon is that var does not create a new local variable but rather reassigns it within the same scope. Additionally, the var keyword does not recognize if as a new scope. For you to produce code that does not override variable values, it is recommended that you declare block-scoped variables.

Hoisting

In the examples that we have explored above, we have declared variables using var and also used a value to initialize it. Subsequently, we can further access or reassign variables that have been declared and initialized. Trying to use variables before declaring and initializing them returns undefined.

// Attempt to use a variable before its declaration
console.log(x);

// Variable task
var x = 300;
Output
undefined

Omitting the var keyword does away with the variable declaration and only tries to initialize it. When we try to use it, we get a ReferenceError and the script execution fails.

// Attempt to use a variable before it is declared
console.log(x);

// Variable task without var
x = 300;
Output
ReferenceError: x is not defined

This happened due to a JavaScript behavior known as hoisting. What it means is that variable and function declarations move to the top of their scope. The first example returns undefined since the declaration was hoisted and not the initialization. Below, we try to further dissect the code we wrote and the interpretation from JavaScript

// The code we used
console.log(x);
var x = 300;

// JavaScript interpretation
var x;
console.log(x);
x = 300;

x was saved to memory by JavaScript before the script was executed. The output we get is undefined and not 300 since x was still called without being defined first. That results in a ReferenceError that halts the script. This is a very good demonstration of the hoisting principle despite the fact that var keyword did not change var's location. It is a problematic behavior among programmers who write code because their expectation is that x is true when it, in reality, it is undefined. Hoisting also leads to some rather unpredictable results as we see in the example below:

// Initialize x in the global scope
var x = 300;

function hoist() {
  // this condition should not affect the outcome of our code
  if (false) {
    var x = 400;
  }
  console.log(x);
}

hoist();
Output
undefined

Initially, x was declared as 300 globally in the example. However, x could change to 200 when an if statement is applied. The value of x should have remained unaffected since the condition was false. However, it was taken to the top of the hoist() function and we ended up with undefined as the value. This is one of the reasons bugs results in programs due to the unpredictability of behavior. We could use a different set of let and const that are block-scoped and would thus not result in hoisting. See the example below:

// We initiate x in the global scope
let x = true;

function hoist() {
  // Initiate x in the function scope
  if (3 === 4) {
    let x = false;
  }
  console.log(x);
}

hoist();
Output
true

When we declare variables twice with let and const, we get an error, but there would be a result with var.

// Try to overwrite a variable that is declared with var
var x = 2;
var x = 3;

console.log(x);
Output
3
// Attempt to overwrite a variable declared with let
let y = 2;
let y = 3;

console.log(y);
Output
Uncaught SyntaxError: Identifier 'y' has already been declared
In summary, when we introduce variables with var, they are exposed to hoisting since JavaScript may end up saving them in the memory. The result for the behavior may be code with some undefined variables. With let and const variables, however, we can avoid the problem since it will not allow declaration of a variable twice. They also do not allow using variables before declaring them.

JavaScript Constants

You are likely to encounter constants in nearly all programming languages. Constants cannot be either changed or modified. The JavaScript representation of a constant is by the const identifier. It is not possible to reassign values assigned to a const. Commonly, const identifiers are written in uppercase to distinguish them from other variables. Let us explore this concept by initializing a variable SPECIES as a constant with const. any attempt to reassign the variable yields an error:

// Assign the value to const
const SPECIES = "man"; 

// Try to reassign value
SPECIES = "cat";

console.log(SPECIES);
Output
Uncaught TypeError: Assignment to constant variable.

You need to declare and initialize const values at the same time or you will encounter an error:

// Declare the constant but do not initialize it
const DO;

console.log(DO);
Output
Uncaught SyntaxError: Missing initializer in const declaration

When a value cannot change, it is known as immutable, while those that change are mutable. Constants are mutable in that you can modify properties of objects declared with const.

// Create a VEHICLE object with two properties
const VEHICLE = {
    color: "red",
    price: 25000
}

// Modify a property of VEHICLE
CAR.price = 30000;

console.log(CAR);
Output
{ color: 'red', price: 30000 }

Use constants to define what aspects of your programs should not be reassigned. On the contrary, use let to declare a variable that may be modified in the future.

Conclusion

We have explored in this tutorial the concept of variables, rules governing their naming and the method of reassigning values in variables. You may also compare how the approach works with other programming languages.

Don't have an Alibaba Cloud account? Sign up for an account and try over 40 products for free worth up to $1200. Get Started with Alibaba Cloud to learn more.

0 0 0
Share on

Alex

17 posts | 2 followers

You may also like

Comments