DEV Community

Cover image for 8 Ways Variables Are Declared in JavaScript
Steph Crown
Steph Crown

Posted on • Edited on • Originally published at blog.stephcrown.com

8 Ways Variables Are Declared in JavaScript

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,
{
  let x = 2;
  let y = 5;
  console.log("x + y = ", x + y)
}
Enter fullscreen mode Exit fullscreen mode

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

var declaration

var varName = value;

// For example
var example = 45;
Enter fullscreen mode Exit fullscreen mode

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.
var example;
example = 45; // valid
Enter fullscreen mode Exit fullscreen mode
  • We can overwrite a variable declared with var with another variable declaration.
var example = 42;
console.log("first value ", example); // First value 42

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

Enter fullscreen mode Exit fullscreen mode
  • 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.
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;
Enter fullscreen mode Exit fullscreen mode
  • Variables declared with var have global scope when declared outside a function, and function scope when declared inside a function.
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

Enter fullscreen mode Exit fullscreen mode

let declaration

let varName = value;

// For example
let example = 45;
Enter fullscreen mode Exit fullscreen mode

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.
let example;
example = 45; // valid
Enter fullscreen mode Exit fullscreen mode
  • A variable declared with let cannot be re-declared in the same scope.
let example = 42;
console.log("first value ", example);

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

Enter fullscreen mode Exit fullscreen mode
  • 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.
console.log("value ", example);
let example = 75; // ReferenceError: Cannot access 'example' before initialization
Enter fullscreen mode Exit fullscreen mode
  • Variables declared with let have block scope.
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
}

Enter fullscreen mode Exit fullscreen mode

const declaration

const varName = value;

// For example
const example = 45;
Enter fullscreen mode Exit fullscreen mode

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.

const example; // SyntaxError: Missing initializer in const declaration
example = 45;

const example = 45; // valid
Enter fullscreen mode Exit fullscreen mode
const example = 45;
console.log("example is, ", example); // example is,  45
example = 45; // TypeError: Assignment to constant variable.

Enter fullscreen mode Exit fullscreen mode

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.

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 ]

Enter fullscreen mode Exit fullscreen mode

function declaration

The function keyword is used to declare a variable and assign a function to it. For example,

function foo(bar) {
  return bar;
}
Enter fullscreen mode Exit fullscreen mode

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.

var foo = function(bar) {
  return bar;
}
Enter fullscreen mode Exit fullscreen mode

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
function foo(bar) {
  return bar;
}

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

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

Enter fullscreen mode Exit fullscreen mode
  • 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.
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
Enter fullscreen mode Exit fullscreen mode
  • 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.
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");
};

Enter fullscreen mode Exit fullscreen mode

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.

function foo(x, y) {
  return x + y;
}

console.log(foo(5, 7));
Enter fullscreen mode Exit fullscreen mode

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.
function foo(x, y) {
  x = 10;
  return x + y;
}

console.log(foo(5, 7)); // 17
Enter fullscreen mode Exit fullscreen mode
  • 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.
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);
Enter fullscreen mode Exit fullscreen mode
  • They can be overridden by another variable declaration done with the var keyword.
function foo(x) {
  var x = 20;
  console.log("x is", x); // x is 20
}

foo(5);
Enter fullscreen mode Exit fullscreen mode
  • 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.

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

Enter fullscreen mode Exit fullscreen mode

The catch clause in a try-catch statement

try {
  throw new Error();
} catch (err) {
  console.log(err);
}

Enter fullscreen mode Exit fullscreen mode

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

class Foo {
  constructor(bar) {
    this.bar = bar;
  }
}
Enter fullscreen mode Exit fullscreen mode

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.

let Foo = class {
  constructor(bar) {
    this.bar = bar;
  }
};
Enter fullscreen mode Exit fullscreen mode

import statement

The import keyword is used to import live bindings that are exported from another module.

// bar.js
let foo = 8;
export default foo;
Enter fullscreen mode Exit fullscreen mode
// import
import foo from "./bar.js";

console.log("foo", foo);
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (5)

Collapse
 
fruntend profile image
fruntend

Сongratulations 🥳! Your article hit the top posts for the week - dev.to/fruntend/top-10-posts-for-f...
Keep it up 🫰

Collapse
 
jonrandy profile image
Jon Randy 🎖️ • Edited

Before we can make use of a variable, we have to first declare (create) the variable.

This isn't actually quite true, there is a case you haven't covered where implicit declaration occurs ('we' didn't declare the variable). You kind of covered this with:

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.

but I think it is worth mentioning...

Put this inside a page - it will work just fine:

<script>
   myVar=333
   alert(myVar)
</script>
Enter fullscreen mode Exit fullscreen mode

You only need to explicitly declare a variable if you are in strict mode, where the implicit declaration shown above will not happen. The fact that explicit variable declaration is not actually required is taken advantage of in 'code golf' competitions to shorten code as much as possible.

Using variables in this manner is not good practice however, as they can all end up in the global namespace (window in the case of the browser) - potentially creating a confusing mess.

Collapse
 
stephcrown profile image
Steph Crown • Edited

Well, I'd say that even in this example you gave, a variable was declared, and an assignment was done.

Plus, I don't think the 8 I listed covers everything. It's just 8 Ways of Declaring Variables, not All Ways of Declaring Variables. So I explored 8 of the ways, and it's a good thing you mentioned one other, and there could even be more. The main aim was to make us understand that there are more instances where variables are declared, other than the most common three - var, let, and const.

Thanks again for your observation.

Collapse
 
jonrandy profile image
Jon Randy 🎖️

A variable was declared, yes, but implicitly. It's important to know that JS will do this

Thread Thread
 
stephcrown profile image
Steph Crown

I agree with you. I'll just rephrase the paragraph. Thanks for pointing it out.