8 Ways Variables Are Declared in JavaScript
Tags: javascript, variable, beginners
Published: 2022-10-01 17:52:48

In JavaScript, we can represent a value in its literal form, for example, `5`, `true`, `{a: 5, b: 6}`; or we can store the value in a variable, and anywhere we need to represent that value, we make use of the variable where we stored the value. We can think of the variable as a container for the value.

Before we can make use of a variable, it has to be declared (created). In JavaScript, there are different ways to declare variables. It is more common to say that we can declare variables in three ways, using `var`, `let`, or `const`. But there are even more ways to declare variables in JavaScript, and if you have been writing JavaScript for a while, you may have used some (or all) of them without realizing that they were creating variables.

Generally, any statement that creates a container for a value, and makes it possible to use an identifier to reference that value, is a variable declaration. The eight ways we will explore in this article include,
- `var`
- `let`
- `const` 
- `function`
- Function parameters
- The `catch` clause in a `try-catch` statement
- `class`
- `import`

In the following sections, we will look at how these syntaxes work, how they behave, and the scope of the variables they create. Before we proceed, let us look at what variable scope means.

## What is variable scope?
Variable scope is the area in a program where a variable can be accessed. In JavaScript, there are three types of scope.

- **Global scope.** Variables with global scope can be accessed from anywhere in the program.
- **Function scope.** Variables with function scope can only be accessed in the function that houses them. This means we cannot access the variable from outside the function.
- **Block scope.** Variables with block scope can only be accessed from within the block where they are defined. In JavaScript, a block is used to group zero or more statements. The statements are placed within a pair of curly braces `{}`. For example,
```js
{
  let x = 2;
  let y = 5;
  console.log("x + y = ", x + y)
}
```

With this out of the way, let us explore these different methods of variable declaration.

## `var` declaration
```js
var varName = value;

// For example
var example = 45;
```
Variables declared with the `var` keyword have the following features.
- It is optional to initialize the variable when declaring it, and we can reassign their values at any point in the program.
```js
var example;
example = 45; // valid
```
- We can overwrite a variable declared with `var` with another variable declaration.

```js
var example = 42;
console.log("first value ", example); // First value 42

var example = 75;
console.log("second value ", example); // second value  75

```
- Variables declared with `var` are hoisted. This means that before the execution of the code, their declaration is moved to the top of the scope where they are defined. The effect of this is that we can access the variable even before they are declared. Note that it is only the variable declaration that is moved to the top, not the initialization. This means that if we try to access the value before the declaration, we will get `undefined`. 

```js
console.log("value ", example); // value undefined
var example = 75;


/* This is how JavaScript interpreted the above code */
var example;
console.log("value ", example); // value undefined
example = 75;
```

- Variables declared with `var` have global scope when declared outside a function, and function scope when declared inside a function.

```js
var x = 1; // Global scope

if (true) {
  console.log("inside the block, x is", x); // inside the block, x is 1
  var y = 2; // Global scope
}

function foo() {
  console.log("inside the function, x is ", x); // inside the function, x is 1
  console.log("inside the function, y is ", y); // inside the function, y is 2
  var z = 3; // function scope
  console.log("inside the function, z is ", z); // inside the function, z is 3
}

foo();
console.log("outside the function, z is ", z); // ReferenceError: z is not defined

```

## `let` declaration
```js
let varName = value;

// For example
let example = 45;
```
Variables declared with the `let` keyword have the following features.
- It is optional to initialize the variable in its declaration, and we can reassign their values at any point in the program.
```js
let example;
example = 45; // valid
```
- A variable declared with `let` cannot be re-declared in the same scope.

```js
let example = 42;
console.log("first value ", example);

let example = 75; // SyntaxError: Identifier 'example' has already been declared
console.log("second value ", example);

```

- Variables declared with `let` are not hoisted. This means that if we try to access the value before the declaration, instead of getting `undefined` as we did with `var`, we will get a runtime error. 

```js
console.log("value ", example);
let example = 75; // ReferenceError: Cannot access 'example' before initialization
```

- Variables declared with `let` have block scope.

```js
let x = 1; // Global scope

if (true) {
  let x = 2; // block scope
  console.log("declared in a block, x is", x); // declared in a block, x is 2
}

console.log("outside the block, x is ", x); // outside the block, x is  1

if (true) {
  console.log("inside the block, x is", x); // ReferenceError: Cannot access 'x' before initialization
  let x = 3; // block scope
}

```

## `const` declaration
```js
const varName = value;

// For example
const example = 45;
```
`const` has some similarities with `let`. Variables declared with the `const` keyword have the same scope and hoisting rules as those declared with `let`. The key difference between `const` and `let` is that variables declared with `const` must be initialized as soon as they are declared, and we cannot reassign their values at any point in the program.
```js
const example; // SyntaxError: Missing initializer in const declaration
example = 45;

const example = 45; // valid
```

```js
const example = 45;
console.log("example is, ", example); // example is,  45
example = 45; // TypeError: Assignment to constant variable.

```

It is important for us to note that the fact that `const` variables cannot be reassigned does not imply that they are immutable. This is because their values can still be changed even though the variable itself cannot be re-assigned. This only happens with mutable values - objects and arrays.

```js
const mutableObject = { foo: 5, bar: 6 };
console.log("mutable object, ", mutableObject); // mutable object,  { foo: 5, bar: 6 }
mutableObject.foo = 43;
console.log("mutable object, ", mutableObject); // mutable object,  { foo: 43, bar: 6 }

const mutableArray = [2, 3, 5];
console.log("mutable array", mutableArray); // mutable array [ 2, 3, 5 ]
mutableArray[2] = 44;
console.log("mutableArray", mutableArray); // mutableArray  [ 2, 3, 44 ]

```

## `function` declaration
The `function` keyword is used to declare a variable and assign a function to it. For example,
```js
function foo(bar) {
  return bar;
}
```
This creates a variable named `foo` and assigns the function to it. This is the same as assigning a function as a value to a variable declared with the `var` keyword.


```js
var foo = function(bar) {
  return bar;
}
```

> Note. `function` only declares variables whose value is a function.


Variables declared with the `function` keyword are similar to variables declared with the `var` keyword in the following ways.
- It is possible to overwrite their values with another declaration

```js
function foo(bar) {
  return bar;
}

function foo(bar) {
  return bar * 4;
}

console.log(foo(8)); // 32

```
- They have the same scope as variables declared with the `var` keyword, that is, they have global scope when declared at the top-level or in blocks, and function scope when declared inside another function.

```js
if (true) {
  function foo(bar) {
    return bar;
  }
}

function zoo() {
  function foo(bar) {
    return bar * 4;
  }
  console.log(foo(8)); // 32
}

zoo();
console.log(foo(8)); // 8
```

- They have the same hoisting rule as `var`. This means that we can call a function declared with the `function` keyword even before they are declared. For context, we will declare a function with the `function` keyword, and we will declare another function with the `const` keyword and try to access both before their declaration.

```js
foo(); // I am accessible
function foo(bar) {
  console.log("I am accessible");
}

bar(); // ReferenceError: Cannot access 'bar' before initialization
const bar = () => {
  console.log("I am accessible");
};

``` 

## Function parameters
A function parameter is a variable passed into a function that can be accessed everywhere in the function. When a function with parameters is called, and arguments are passed to the call, for each parameter-argument, a variable is created and the argument is assigned to it as its value. If you are not sure of the difference between function parameters and arguments, [this article explains it](https://blog.stephcrown.com/commonly-confused-terms-in-programming#parameters-and-arguments). 
```js
function foo(x, y) {
  return x + y;
}

console.log(foo(5, 7));
```
Take a look at the function defined above. When we call the function, with 5 and 7 as arguments, it creates two variables `x = 5`, and `y = 7`.

Variables created by function parameters have the following features.
- They can be reassigned.

```js
function foo(x, y) {
  x = 10;
  return x + y;
}

console.log(foo(5, 7)); // 17
```
- Their values are not always initialized immediately they are declared. This behavior depends on the arguments passed to it. For example, if a function has two parameters and while calling it, we pass one argument to it, the variable that the second parameter will create will be assigned a value of undefined, and can be initialized within the function.

```js
function foo(x, y) {
  console.log("y before initialization is ", y); // y before initialization is  undefined
  y = 10;
  console.log("y after initialization is ", y); // y after initialization is  10
}

foo(5);
```

- They can be overridden by another variable declaration done with the `var` keyword.

```js
function foo(x) {
  var x = 20;
  console.log("x is", x); // x is 20
}

foo(5);
```

- The variables created by function parameters are declared immediately the function is called, so we cannot access it before its declaration.

- Function parameters are not hoisted to the top of the program

- Function parameters are function-scoped. This means that they can only be accessed throughout the function where they are declared. 


```js
function foo(x) {
  console.log("x inside the function is ", x); // x inside the function is  5
}

foo(5);
console.log("x outside the function is ", x); // ReferenceError: x is not defined

```

## The `catch` clause in a `try-catch` statement
```js
try {
  throw new Error();
} catch (err) {
  console.log(err);
}

```
A `try-catch` statement is made up of a `try` block and a `catch` block. The content of the `try` block is first executed. If an exception (or error) is thrown in the `try` block, the `catch` block catches the error and the content of the `catch` block is executed. When this happens, JavaScript creates a variable that stores the exception (or error) caught by the `catch` block. We can give the variable any name we want if we intend to make use of it. In our case, we name it `err`.

This `err` variable is block-scoped. This means that we can only access it in the `catch` block. This variable behaves in the same way as a variable declared with the `let` keyword.

## `class` declaration
```js
class Foo {
  constructor(bar) {
    this.bar = bar;
  }
}
```
The `class` keyword creates a variable and assigns a class to it. A variable created this way behaves the same way as a variable created with the `let` keyword. The above class definition is similar to this.

```js
let Foo = class {
  constructor(bar) {
    this.bar = bar;
  }
};
```

## `import` statement
The `import` keyword is used to import live bindings that are exported from another module. 
```js
// bar.js
let foo = 8;
export default foo;
```

```js
// import
import foo from "./bar.js";

console.log("foo", foo);
```
There are different ways to use the `import` keyword to import values from another module. Each method creates a new variable in the current module and assigns it the value that it imported. The above snippet is similar to creating a variable `foo` and assigning it a value of 8 which was imported from `"./bar.js"`.

Variables declared this way are constants, and behave in the same way as variables created with the `const` keyword.
> Note. `import` declarations can only be done at the top-level of a module.

## In conclusion
We have come to the end of this article. We have been able to break away from the subconscious knowledge that there are three methods of declaring variables in JavaScript, and we explored eight different ways that it is done. 

It was wonderful learning all these with you. 

Till we meet again,
Bye.