Course: JavaScript

Progress (0%)

  1. Foundation

  2. Numbers

  3. Strings

  4. Conditions

  5. Loops

  6. Arrays

  7. Functions

  8. Objects

  9. Exceptions

  10. HTML DOM

  11. CSSOM

  12. Events

  13. Drag and Drop

  14. opt Touch Events

  15. Misc

  16. Project: Analog Clock

JavaScript Variables

Chapter 5 41 mins

Learning outcomes:

  1. A quick review of creating variables
  2. Variations of using var
  3. Rules and tips to naming variables
  4. Checking for a variable's existence
  5. Variable hoisting
  6. The let keyword

Introduction

In the previous JavaScript Basics chapter, we briefly discussed about variables in the language. Now we shall take it from there and explore many of the vital concepts associated with variables in JavaScript and programming, in general.

Specifically, we'll start with a very quick review of creating and using variables, then moving over to consider the different variations of defining variables using var. Not only this, but we'll also see the rules for naming variables in JavaScript and some tips on how to come up with effective and meaningful variable names.

Lastly, we'll end the discussion by touching upon the dynamically-typed nature of JavaScript, understanding how to check for a given variable's existence using typeof, and seeing the more recent way of defining variables using let.

Let's begin.

A quick review

As we saw in the previous JavaScript Basics chapter, the var keyword can be used to create a variable in JavaScript.

Shown below is the syntax of defining a variable using var:

var variableName = value;

The var keyword is followed by the name of the variable to create (denoted as variableName), followed by an equals sign (=), followed by the initial value to assign to the variable (denoted as value).

The first part in this statement, i.e. var variableName, is usually known as the variable's declaration. It serves to introduce a new identifier into the execution environment.

The second part, i.e. = value, is usually known as the variable's initialization. As the name suggests, it serves to set the variable to an initial (starting) value at the time of its declaration.

To change the value of an existing variable, we just use the same equals sign (=) followed by the new value to put inside the variable, as shown below:

variableName = newValue;

This statement is commonly referred to as the variable's assignment.

In the code below, we define two variables x and y holding the values 10 and 20, respectively.

var x = 10;
var y = 20;

Working with these variables is just working with the numbers 10 and 20 directly. That is, we can add them, multiply them, log them, assign them to other variables, and so on and so forth.

Following, we experiment around with the variables x and y created before:

var x = 10;
var y = 20;

console.log(x);
console.log(y);

console.log(x + y);
console.log(50 * x * y);
10 20 30 10000

Simple.

Let's consider another example, this time changing the value of the variable amid the program:

var x = 10;
console.log(2 ** x);

x = 5;
console.log(2 ** x)
1024 32

Here, first, x is equal to 10 and so the expression 2 ** x becomes 2 ** 10 which evaluates to 1024. Next up, x is changed to 5, and likewise the expression 2 ** x becomes 2 ** 5 which evaluates to 32.

This illustrates how we could change the value of a variable at any point in a program.

Alright, it's time for a quick task.

Write a piece of code to accomplish the following.

Create a variable text holding the text shown below,

The ' character is called an apostrophe.

and then log the text to the console.

Since the given text contains a single quote (') character in it, we'll denote the string using a pair of double quotes (""):

var text = "The ' character is called an apostrophe.";
console.log(text);
The ' character is called an apostrophe.

Variations of using var

While creating variables using var, there isn't just one fixed syntax for doing so. We can change it according to our need and preference.

Let's see what this means.

Suppose we want to create three variables x, y and z holding the values 10, 20 and 30, respectively.

The obvious way to do this is as follows:

var x = 10;
var y = 20;
var z = 30;

Each variable is defined separately, on a new line, with a separate var keyword.

Another way is to just use var once and then define all the individual variables one-by-one, without having to type var again and again.

Syntactically, this could be expressed as this:

var variableName1 = value1,
    variableName2 = value2,
    variableName3 = value3,
    ...
    variableName3 = value4;

Everything is the exact same as before, with the exception of the var keyword and the last character — previously it was a semicolon (;) to indicate the end of the statement, but now it's a comma (,).

When a variable definition ends with a comma (,), it means that more variable definitions follow along. It's only when we put a semicolon (;) in the end that the parser figures out that the variable definitions have ended.

So going with this approach, the same code above could also be expressed as follows:

var x = 10,
    y = 20,
    z = 30;

Note that there is no semicolon at the end of the first line, neither at the end of the second line. The semicolon is only appended to the third line where it ends the whole set of definitions.

Now which variation shall we use?

Well, it's totally a matter of preference.

We'll go with our old method of using a new var keyword for each variable definition.

This is because we feel that it keeps the code readable and doesn't introduce any awkward indentation before all the subsequent variable definitions after the first one. But more importantly, there is always a chance of clerical errors when using the one-var-keyword approach.

The problem with using , in variable definitions

When using commas (,) with the var keyword, there is always a chance to make a typo and use ; instead of , at the end of a variable definition which is followed by another definition.

This can modify the meaning of the following variable definition statement completely.

To understand what this means, consider the code below:

var x = 10;
    y = 20,
    z = 30;

console.log(x + y + z);

Everything looks fine at first glance, so let's go on and run this.

Here's what gets displayed in the console:

60

Although, we did indeed get the expected output, we forget to fix a typo in the code. Can you spot it?

The first variable definition statement was meant to end with , but it instead ended with ;. Unfortunately, JavaScript doesn't flag any sort of errors here, which is surprising.

In order to get our code to throw errors when we forget to correct such clerical typos, JavaScript provides us with a strict mode. A program could be entered into strict mode by using 'use strict' at the start of the script.

Here's the code above rewritten to leverage strict mode:

'use strict'

var x = 10;
    y = 20,
    z = 30;

console.log(x + y + z);

Now when we run it, here's what gets displayed in the code:

Uncaught ReferenceError: y is not defined

The strict mode is able to pick up the typo and raise an error. Since the code seemed absolutely fine to us, after seeing this error, we immediately inspect the code and spot the ; typo in line 1 at the end of the statement. Great.

We'll learn more about strict mode later on in this unit.

At this point, it might definitely seem that using commas to define multiple variables at once is not useful at all.

Well, that's not the case.

If we are just wanting to declare multiple variables at once without initializations, then the comma syntax proves to be really concise.

Now before we can see it in action, we ought to see another variation of creating variables in JavaScript. That is to just declare the variable without any initializer.

As you can see in the syntax below, it's possible to omit the initialization from a variable definition — what we're left with then is just the declaration:

var variableName;

When this statement executes, the variable comes into existence with the initial value undefined (which is JavaScript's way to signal the absence of a value).

Alright, let's come back to the point.

Suppose we want to declare three variables x, y and z but not assign them any value at the moment. Using this short syntax, we can simply declare them all at once by separating each variable with a comma (,).

The code below demonstrates this:

var x, y, z;

Now compare this with:

var x;
var y;
var z;

Which one is more readable and concise?

Clearly the first one. This is the syntax we'll use throughout this course when we want to declare multiple variables at once without any initializer.

Rules for naming variables

Almost all programming languages enforce certain rules on the programmer when naming variables. This is done to prevent one from creating names that could introduce ambiguity into the respective program.

JavaScript is no way behind — it has a couple of rules as well, that govern variable naming. These rules are quite standard ones and used in many other programming languages too.

The rules we must follow when naming variables in JavaScript are as follows:

  1. Names can only contain alphanumeric characters (a-z, A-Z, 0-9) and the _ (underscore) and $ (dollar sign) characters; nothing else. Hence, first-name is invalid since it contains a hyphen (-) which is illegal to put in a variable name.
  2. Names can't begin with a digit. Hence, 2nd is invalid.
  3. Names can't contain spaces. Hence, first word is invalid.
  4. Names can't be reserved keywords. Hence, var is invalid.

Tips for naming variables

In this section, we aim to discuss a handful of tips to consider when naming variables in JavaScript, including which casing convention to use in order to break long words.

Be descriptive

A variable's name shall clearly describe what it's meant to hold.

For instance, suppose that you have to store a user's name in a variable. It would be really bad if you name the variable a (or x or u for 'user', or any random character). The name a doesn't tell much about what's stored in the variable.

A much better name would be username, or uname.

Well frankly speaking, the latter, i.e. uname, is also not very descriptive and sometimes could be ambiguous — uname could also stand for 'universal name', 'unsatisfactory name', or maybe even 'unique name'.

Don't be overly descriptive

Creating descriptive variable names is desirable, but we have to make sure that we remain within the bounds of description. Even too much description can be problematic.

Suppose we want to create a variable that stores the first name of a user. Being exceptionally descriptive, we could name it thefirstnameofuser, although this would be more than the required amount of description.

A better name would be firstname.

We have to remain in between the scale of descriptiveness — not too little, and not too much.

Abbreviate long words

Sometimes, it's really helpful to abbreviate long words in a given name to short and simple words, given that the abbreviation seems sensible.

For example, the variable dbname could work well instead of databasename. Here, we've abbreviated 'database' to 'db'.

The abbreviation 'db' for 'database' is quite a common one out there.

But keep in mind that abbreviations don't always work well.

For instance, naming a variable that holds the name of an object's property as pname would be a complete mess. pname could mean 'property name' or 'panel name' or 'previous name'.

A much better name would be propname — with the word 'property' abbreviated down to 'prop'.

Use a casing convention to break words

When a variable's name contains more than one word, it's desirable to use some casing convention to be able to distinguish between them easily while reading the variable.

Let's say we have a variable questionsasked that holds the number of questions asked in a quiz program. Seeing this name doesn't right away tell us about the individual words in it. Does it?

We have to gaze at the name for a while before we realize that it says 'questions asked'.

Worse yet, in some words the name could even be misinterpreted by the reader. For example, what can you read in idenum? Did you read it as 'ide num' or as 'id enum' ?

Well, the variable meant 'id enum' for 'ID enumeration'.

So to solve such ambiguities and make long variable names readable, we ought to use casing conventions.

Some common casing conventions are as follows:

  1. camelCasing: every word's first letter is uppercased except for that of the first word. Camel casing is the casing used in JavaScript. Here are some identifier names from JavaScript: indexOf, getElementById, querySelectorAll.
  2. PascalCasing: every word's first character is uppercased. C# uses Pascal casing for almost all identifiers. Some examples from C# are as follows: WriteLine, ReadLine, GetType.
  3. snake_casing: every word is lowercased and separated from the other using the _ (underscore) character. PHP uses snake casing for most of its predefined functions. Some examples from PHP are as follows: array_push, mysqli_connect, str_split.
  4. SCREAMING_SNAKE_CASING: every word is uppercased and separated from the other using the _ (underscore) character. This casing is commonly used to denote constants in many programming languages, including JavaScript. Some examples are: MAX_VALUE, MAX_SAFE_INTEGER.
As we shall see later in this course, identifier names could not only describe the data they point to, but also to what the identifier itself is i.e. is it a class, a constant, a method and so on.

Coming back to our example, the variable questionsasked could be renamed to one of the following:

  1. questionsAsked in camel casing.
  2. QuestionsAsked in Pascal casing.
  3. questions_asked in snake casing.
  4. QUESTIONS_ASKED in screaming snake casing.

Now it doesn't require much effort on our side to distinguish between the different words used in the variable's name.

But which one of these should we use?

Which casing convention to use in JavaScript?

The two most common conventions used for naming variables in most of the programming languages out there are camel casing and snake casing.

The question of 'which convention to use in JavaScript' really boils down to the question of 'whether to use camel casing or snake casing in JavaScript'.

Honestly speaking, this is solely a matter of preference. If you like camel casing, go with it. Similarly, if snake casing appeals you, go with it. Whatever you choose, make sure to stick with it — consistency is a must!

In this course, we'll use the camel casing convention to name variables. The reason is extremely simply — it's the convention used throughout JavaScript for function and method names.

Long story short, naming isn't any scientific theory to learn — it's purely an art.

In your journey of programming, you'll be able to come up with extremely effective variable names with:

  1. Experience — the more you code, the better you become at naming.
  2. Lots of trial and error — keep on altering the name of the variable until you feel that it communicates its underlying purpose in the best way.

Checking for a variable's existence

When working in a dynamic language such as JavaScript, it's extremely useful to have the feature of checking whether a given variable really exists before we use it.

For instance, consider the code below:

console.log(x);
Uncaught ReferenceError: x is not defined at <anonymous>:1:13

We log the variable x and get an error thrown back at us. It's simply because there isn't any definition of x anywhere in the code.

The way we check for the existence of a variable is via typeof.

The typeof operator basically returns the type of a given value.

Here's its syntax:

typeof value

value is the value whose type we ought to determine.

When provided with a non-existent variable, typeof returns the string 'undefined'. This return value can be used to determine whether a variable is accessible or not.

That is, we can compare the return value of typeof as applied on a non-existent variable with the string 'undefined' using the non-equality (!==) operator.

The non-equality operator, denoted as !==, compares two values together and determines whether they are not equal to one another. If the given values are not equal, it evaluates down to the Boolean value true, or else to false.

For example, consider the code below:

var x = 10;

console.log(typeof x !== 'undefined');
console.log(typeof y !== 'undefined');
true false

Here we define a variable x and then check whether it exists or not, by comparing typeof x with 'undefined' for equality. Since x exists, we get true output by the first log statement. However, since there is no such variable as y, the second log statement outputs false.

One thing to note here is that typeof deals with a non-existent variable specially. That is, in a normal expression, if we refer to a non-existent variable, JavaScript throws an error. However, in typeof, doing the same doesn't lead to any errors whatsoever. This is because the internal engine is configured to treat non-existent variables differently when used in a typeof expression.

Moving on, one extremely important thing to keep in mind while performing such a variable existence check is that typeof returns 'undefined' even for a variable that's declared but not assigned a value.

This can be seen as follows:

console.log(typeof x !== 'undefined');

var y;
console.log(typeof y !== 'undefined');
false false

Here, the variable x doesn't exist and so typeof x returns 'undefined'. However, the variable y does exist, yet it faces the same fate as x. That is, typeof y also returns 'undefined'.

For us, this means that if we get 'undefined' returned by typeof while inspecting a given variable, then we can NOT be definitely sure that the variable doesn't exist.

However, at least we can safely assume that the variable isn't of use to us (either because it's non-existent or not assigned a value) and hence not proceed with consuming its value for any purpose in our program.

Hoisting of var declarations

When a JavaScript program is parsed and ready to be executed, all of the var declarations in there are put into action before executing any other statement in the code.

This is formally known as variable hoisting.

Executing all var declaration statements before any other statement in JavaScript is referred to as variable hoisting.

In practice, hoisting seems to bring all variable declaration statements to the top-most location of wherever they are defined.

In reality, however, there isn't anything such as 'bringing the variable declarations up' — it's just an analogy drawn to help the developer understand what essentially is happening.

Due to the effects of hoisting, a variable in JavaScript could be assigned a value in source code way long before it's actually declared via the var keyword.

Although no one would ever want to do this, it's a feature to be aware of so that we don't mistakenly write code that executes contrary to how we expect it to.

For instance, consider the following code:

str = 'Hoisting';
console.log(str);

var str;
Hoisting

Despite the fact that we assign a value to the variable str in line 1 before it's actually declared in line 4, this code doesn't flag any errors whatsoever, even though it should've.

That's because during execution, it's the same as the following code:

var str;
str = 'Hoisting';
console.log(str);

This is due to the effect of the hoisting of str's declaration.

Keep in mind that JavaScript only hoists variable declarations, NOT the initializations within the declaration statements.

For example, consider the following code:

console.log(str);

var str2 = 'Hoisting';
undefined

As is apparent by the undefined log, only the declaration of str here (in line 3) is hoisted, NOT its initialization = 'Hoisting'.

The let keyword

In the early days of JavaScript, there was one and only one way of defining variables in the language, which which've explored in quite detail above, i.e. using var.

The let keyword was introduced in JavaScript with the advent of ECMAScript 6. It's a new way of defining variables.

In particular, let creates block-scoped variables. In contrast, var does not create block-scoped variables. We'll explore variable scopes at length in the JavaScript Variable Scoping chapter, and it's there that we'll reiterate on this idea of block-scoped variables created using let.

Syntactically, let is akin to var:

let variableName = value;

In the code below, we define two variables x and y using let and use them just how we've been used to using variables uptil now:

let x = 10;
let y = 20;

console.log(x + y);
console.log(x * y);
console.log(x / y + y);
30 200 20.5

If we want to, we can define multiple variables at once with let by separating their declarations with a comma (,). We can even omit the initialization of variables.

Consider the following code where we define three variables using let and then set them later on:

let x, y, z;

x = 10;
y = 20;
z = 30;

console.log(x + y + z);
60

Simple as var, isn't it?

Apart from differing scope of the variables that it creates, which we'll learn about later on in this unit in JavaScript Variable Scoping, let differs from var in that let declarations are not hoisted.

Accessing a let variable before its declaration leads to an error; the standard refers to such a scenario as a temporal dead zone.

The temporal dead zone for a given let variable is simply referred to the region prior to the variable's declaration in the source code, where we can NOT access the variable.

Remember that the temporal dead zone doesn't apply to var variables.

The way the engine is able to determine the temporal dead zone for a let variable is by analyzing all let declarations before running the code. Then the region before the let declaration becomes a temporal dead zone for the respective variable.

Let's see an example.

In the code below, we try to access the variable x before it's declared (via let):

console.log(x);

let x = 10;

Since the access is made in the temporal dead zone of the variable, we get an error:

Uncaught ReferenceError: x is not defined at <anonymous>:1:13

This is an ideal scenario. We do expect JavaScript to throw an error when accessing a variable prior to its declaration, and let is exactly — in fact, only — what allows us to do this.

As we saw in the sections above, if rewrite this same code using var, no errors would be thrown, and that's because of the effects of var hoisting.

What to use: let or var?

This is a really good question, the answer to which is purely preferential and sometimes even dependent on the problem being solved.

Although let is more modern approach to creating variables in JavaScript, there's absolutely nothing such as 'var is poor in performance than let'. It isn't at all inefficient to use var in modern code.

In fact, for newbie developers, understanding how var works and how it differs from let is important to be able to truly appreciate the power of let in certain use cases and also realize that there isn't any reason to believe that var might perform poorly than let.

There surely are certain places where using let can simplify code drastically, but majority of the times, there isn't much of a difference if we use let or var.

So, to answer the question: if you want to, you could surely switch to using let instead of var, or keep using the latter. It's mostly, if not completely, a preferential choice.

But whatever you choose, make sure to stay consistent with it.

For an even extended discussion, you can refer to the following question on StackOverflow: Is there a performance difference between 'let' and 'var' in JavaScript.

Throughout this course, however, we stick to using var and that's because we've been using it for a very long time now and so changing all the existing code to use let won't be very feasible. But all the code examples shown can easily be swapped with let variables.