# Mastering JavaScript: All About Variables

One of the fundamental aspects of JavaScript is variable declaration. Understanding how to declare and use variables correctly is crucial for writing efficient and error-free code. In this article, we will explore variable declarations in JavaScript, hoisting, the Temporal Dead Zone (TDZ), variable naming rules, and variable scopes with relevant examples to make these concepts easy to understand.

## Variable Declarations in JavaScript

In JavaScript, variables can be declared using `var`, `let`, and `const`. Each of these keywords has different behaviours and use cases.

![Let us finally understand ,  and  in JavaScript!](https://cdn.hashnode.com/res/hashnode/image/upload/v1611744989589/j-4J_pIFh.png?auto=compress,format&format=webp align="left")

### `var`

`var` is the traditional way to declare variables in JavaScript. It is function-scoped, meaning it is accessible within the function it is declared in. However, it has some quirks due to hoisting, which can lead to unexpected behaviour.

#### Example:

```javascript
function exampleVar() {
  var x = 10;
  if (true) {
    var x = 20; // same variable!
    console.log(x); // 20
  }
  console.log(x); // 20
}
exampleVar();
```

In the above example, the variable `x` declared inside the `if` block using `var` affects the variable `x` declared outside the block because `var` is function-scoped.

> Note: Variables declared with `var` can be redeclared within the same scope without an error, which can sometimes cause bugs.

### `let`

`let` is block-scoped, meaning it is only accessible within the block it is declared in. It is a better choice than `var` for most situations because it avoids the pitfalls associated with `var`.

#### Example:

```javascript
function exampleLet() {
  let y = 10;
  if (true) {
    let y = 20; // different variable
    console.log(y); // 20
  }
  console.log(y); // 10
}
exampleLet();
```

In this example, the `let` keyword ensures that the `y` variable inside the `if` block is different from the `y` variable outside the block.

> Note: Variables declared with `let` cannot be redeclared in the same scope. They also have a "temporal dead zone" from the start of the block until the declaration is encountered.

### `const`

`const` is also block-scoped like `let`, but it is used to declare constants. Variables declared with `const` cannot be reassigned.

#### Example:

```javascript
function exampleConst() {
  const z = 10;
  z = 20; // Uncaught TypeError: Assignment to constant variable.
  console.log(z); // 10
}
exampleConst();
```

In the above example, attempting to reassign a `const` variable results in an error.

> Note: While `const` prevents reassignment of the variable, it does not make the value immutable. For objects and arrays declared with `const`, their properties or elements can still be changed.

```javascript
const arr = [1, 2, 3];
arr.push(4); // This is allowed
console.log(arr); // [1, 2, 3, 4]
```

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1722067594510/6061aefb-411a-4894-a851-97fa2faef880.png align="center")

## Hoisting

Hoisting is JavaScript's default behavior of moving declarations to the top of the current scope. However, only the declarations are hoisted, not the initialization.

### Example:

```javascript
console.log(a); // undefined
var a = 10;

console.log(b); // Uncaught ReferenceError: Cannot access 'b' before initialization
let b = 20;

console.log(c); // Uncaught ReferenceError: Cannot access 'c' before initialization
const c = 30;
```

In this example, the `var` declaration is hoisted, so `a` is undefined before its assignment. However, `let` and `const` declarations are not initialized until their line of code is executed, resulting in a reference error.

> Note: Hoisting can lead to bugs, especially with `var` declarations, because it might not be clear at a glance where the variable is declared.

## Temporal Dead Zone (TDZ)

The Temporal Dead Zone (TDZ) is a behavior that applies to variables declared using `let` and `const`. It refers to the period from the start of a block until the variable is declared and initialized. During this period, any attempt to access the variable will result in a `ReferenceError`.

### Example:

```javascript
{
  // TDZ starts here for 'x' and 'y'
  console.log(x); // Uncaught ReferenceError: Cannot access 'x' before initialization
  console.log(y); // Uncaught ReferenceError: Cannot access 'y' before initialization

  let x = 10;
  const y = 20;

  // TDZ ends here for 'x' and 'y'
  console.log(x); // 10
  console.log(y); // 20
}
```

In this example, trying to access `x` or `y` before their declarations results in a `ReferenceError` because they are in the TDZ.

### Why TDZ Exists

The TDZ exists to catch errors early and ensure that variables are not accessed before they are initialized. This makes the code more predictable and easier to debug.

#### Example:

```javascript
function checkTDZ(condition) {
  if (condition) {
    console.log(value); // Uncaught ReferenceError: Cannot access 'value' before initialization
    let value = "Hello, TDZ!";
  }
}
checkTDZ(true);
```

Here, accessing `value` before its declaration throws a `ReferenceError`, preventing potential bugs that could arise from using an uninitialized variable.

### TDZ in Loops

TDZ also applies to variables declared with `let` and `const` in loops.

#### Example:

```javascript
for (let i = 0; i < 3; i++) {
  console.log(j); // Uncaught ReferenceError: Cannot access 'j' before initialization
  let j = i * 2;
  console.log(j); // 0, 2, 4
}
```

In this loop, `j` is in the TDZ each time the loop starts until its declaration. Accessing `j` before its declaration in the loop block results in a `ReferenceError`.

> Note: The TDZ ensures that variables are not used before they are declared, which can prevent subtle bugs and makes the code easier to understand.

## Variable Naming Rules

When naming variables in JavaScript, follow these rules:

1. **Start with a letter, underscore (\_), or dollar sign ($)**:
    
    ```javascript
    let _variable;
    let $variable;
    let variableName;
    ```
    
2. **Subsequent characters can be letters, digits, underscores, or dollar signs**:
    
    ```javascript
    let var123;
    let _var_name;
    let $varName;
    ```
    
3. **Case-sensitive**:
    
    ```javascript
    let myVar;
    let MyVar; // Different variable from myVar
    ```
    
4. **Avoid reserved keywords**:
    
    ```javascript
    // Invalid variable names:
    // let let;
    // let const;
    // let function;
    ```
    

> Note: Consider using camelCase for variable names and constants in all-uppercase with underscores separating words, as these are common conventions in JavaScript.

## Variable Scopes

Variable scope determines the accessibility of variables. JavaScript has three types of scopes: block scope, function scope, and global scope.

![Understanding Scopes in JavaScript | by Eylem Aytas | Medium](https://miro.medium.com/v2/resize:fit:600/1*SC9EEunh3HzV2aMkFKj6OQ.png align="center")

### Block Scope

Variables declared with `let` and `const` are block-scoped.

#### Example:

```javascript
{
  let a = 10;
  const b = 20;
  console.log(a); // 10
  console.log(b); // 20
}
// console.log(a); // Uncaught ReferenceError: a is not defined
// console.log(b); // Uncaught ReferenceError: b is not defined
```

In this example, `a` and `b` are only accessible within the block they are declared in.

### Function Scope

Variables declared with `var` are function-scoped.

#### Example:

```javascript
function myFunction() {
  var x = 10;
  console.log(x); // 10
}
myFunction();
// console.log(x); // Uncaught ReferenceError: x is not defined
```

Here, `x` is only accessible within the function `myFunction`.

> Note: Function scope is also relevant for `let` and `const`. If they are declared inside a function, they won't be accessible outside it.

### Global Scope

Variables declared outside any function or block are globally scoped and can be accessed anywhere in the code.

#### Example:

```javascript
var globalVar = 10;
let globalLet = 20;
const globalConst = 30;

function testGlobalScope() {
  console.log(globalVar); // 10
  console.log(globalLet); // 20
  console.log(globalConst); // 30
}
testGlobalScope();

console.log(globalVar); // 10
console.log(globalLet); // 20
console.log(globalConst); // 30
```

In this example, `globalVar`, `globalLet`, and `globalConst` are accessible both inside and outside the function `testGlobalScope`.

> Note: Avoid using global variables whenever possible. They can lead to conflicts and hard-to-debug issues, especially in larger codebases.

## Conclusion

Understanding variable declarations, hoisting, the Temporal Dead Zone (TDZ), naming rules, and scopes in JavaScript is essential for writing clean and efficient code. By using `let` and `const` instead of `var`, you can avoid common pitfalls and make your code more predictable. Remember the scope rules to ensure your variables are accessible where you need them and protected where you don’t.

In the next article, we will dive deeper into the core of JavaScript by exploring its various data types. From primitive types like **strings**, **numbers**, and **booleans** to complex **objects** and the `typeof` operator, you will gain a thorough understanding of how to effectively work with data in JavaScript. Stay tuned and happy coding!

%%[bmc-singhlify]
