
Creating Variables
Variable creation is the means to assign a value to a symbol. In this circumstance, a symbol is a textual representation of the data, much like a container, which can be used to move data through your program. It also improves the legibility of your code. There are multiple ways to create variables, including assignment to the global scope or through the use of either the var, let, or const keywords.
A Note on Referencing
Even at this early stage, it must be highlighted that JavaScript's referencing functionality can get rather confusing. The presence of closures, prototypes, global and local memory stacks, variable assignment variations, and function invocation options can leave even seasoned programmers scratching their heads. Each of the aforementioned features supports JavaScript as a formidable and flexible programming language that's able to challenge most other platforms for almost any purpose. While it does deepen JavaScript's learning curve, mastering these concepts can be extremely rewarding.
This chapter highlights the very basics of data referencing and attempts to not confuse matters any more than necessary. Only referencing with regard to data at the global level will be discussed.
Global Assignment
Assigning a variable without the use of var, let, or const will place the variable into the global scope. This value will then be accessible anywhere in your application unless a variable of the same name exists within that scope. Redeclaring the same variable name without the use of a preceding keyword will overwrite the global reference, even if it's assigned within a different scope.
Declaring globally in a browser environment is equivalent to declaring the value on the global window object as a field.
Declaring with var
Preceding variable assignment with the var keyword places the variable into function scope. This means the variable only exists at the same function as the assignment, but not outside that function. Declaring with var in the global scope is equivalent to declaring without the var keyword.
Redeclaring a variable with var, but in a nested scope, will not overwrite the variable of the same name in the outer scope.
Using the var keyword, variables can be scoped (declared) even after they are used within the same scope. This is due to variable hoisting. Hoisting was explained in Chapter 4, JavaScript Libraries and Frameworks.
Declaring with let
The let keyword has a narrower scope. While var is considered to be functionally scoped, the let keyword is block scoped. This means that variables that are created with var exist throughout a function's scope level, while let-declared variables are created and used at the block level, such as in if conditional blocks or for loops.
For example, using let, a variable can be temporarily overwritten within a for loop while not changing a variable of the same name in the outer function. However, if var is used instead, the outer variable will be changed:
var a=0;
for(var a in [0, 1]);
console.log( a ); // ==> a is now 1 (as modified by the loop)
In the preceding example, the variable declared in the for loop matches the symbol declared outside of it. As such, the same variable reference is modified. However, in the following example, the result is different, as the let-declared variable only exists within the context of the for loop, meaning the outside variable of the same name is left untouched:
var a=0;
for(let a in [0, 1]);
console.log( a ); // ==> a is still 0 (not modified by the loop)
Contrary to var, let-declared variables are not hoisted. If a scope declares a variable with let, accessing that variable before that let declaration statement (within the same scope or in any inner scope) will raise an error (this is regardless of whether a variable with the same name has been created in an outer scope):
glob=1; {glob=2; let glob=3;} // ==> can't access lexical declaration `glob' before
initialization
glob=1; {glob=2; var glob=3;} // ==> accepted syntax
Declaring with const
The const keyword works with the same scoping and hoisting rules as the let keyword. The difference with const is that it is assumed the variable will not change throughout its lifetime. Using const allows the JavaScript engine to make certain optimizations at compile time since it expects the data to remain constant at runtime.
It is possible to create a new variable assignment with the same name in a nested function scope, but it will not be possible to modify a variable of the same name using global scoping rules.
Note
Declaring a variable with var or let, but without assigning a value, will result in the variable containing undefined. The undefined value will be covered a little later in this chapter.
Exercise 5.01: Variables and Scope
In this exercise, we will use the browser's JavaScript Read-Eval-Print Loop (REPL) to experiment with variable assignment and scope. Let's get started:
- Launch your browser and open the developer tools console. In Chrome, you can do this by pressing the F12 key.
- Ensure the Console tab is selected:
Figure 5.1: The Console tab
- At the prompt, enter the following commands, pressing Enter at the end of each line:
const i = 10;
console.log(i);
// -> 10
The console.log command writes the value of i to the console.
- Next, create a function that also initializes a variable of the same name, as follows:
const f = function() {
var i = 20;
console.log(i);
};
- Invoke the function to print the variable that exists within the function scope. If you then print the global variable, you will see it has not been modified:
f();
// -> 20
console.log(i);
// -> 10
- Next, try the let keyword:
if (true) {
let i = 15;
console.log(i);
}
// -> 15
console.log(i);
// -> 10
As you can see, the let assignment only exists for the lifetime of the block that follows the if statement.
- Close the browser tab. Open a new tab and open the console again (otherwise, you won't be able to re-assign i as a variable). Now, try the same with var. You will see that the variable declaration raises an error because it conflicts with the i variable outside of the conditional block:
i = 10;
if (true) {
var i = 15;
console.log(i);
}
// -> 15
console.log(i);
// -> 15

Figure 5.2: Exercise 5.01 output
Understanding the scope surrounding a variable is important for the correct execution of your application, as well as for minimizing bugs. Try to keep a mental note of the positioning and use of each variable as you work. Utilizing functional paradigms, as discussed in Chapter 13, JavaScript Programming Paradigms, will also help alleviate any discrepancies in variable scoping.
Identifying a Variable's Type
So far, you have created variables and output their value to the browser's console. In order to get the most out of the content of this chapter, however, it would be helpful to be able to identify the content of a variable. JavaScript is known as a weakly typed language because a variable can hold a string one moment, but then an integer the
next. By being able to identify the type of value stored in a variable, you prevent errors occurring where you attempt to process a value you expected to be of a different type.
The typeof keyword exists to do just that. By preceding a variable with the typeof keyword, the returned value is the type of the variable represented as a string.
The typeof keyword evaluates with the following type mapping:

Figure 5.3: Types and responses
The null type evaluates as "object". This anomaly originates from the earliest incarnations of JavaScript where data types were tagged internally with an integer value. Object types were tagged with 0, while the null value existed as a null pointer (or 0x00 as a value). As the two expressions were identical, determining the type of null resulted in the same type as Object. This same anomaly still exists in JavaScript today. Therefore, when determining whether a type is an Object, we must also compare it with null:
var value = [1, 2, 3]; // an array - which is also an object
if (typeof value === "object" && value != null) {
console.log("value is an object");
}
Exercise 5.02: Evaluating Types from Variables
In this exercise, we will create a function that outputs the type of whatever variable is passed to it. Let's get started:
- At the command prompt, enter the following line to declare the function signature:
var printType = function(val) {
This function accepts a single variable, which will be the variable to analyze.
- Due to the Null value caveat, you must check for this, first. Here, compare val to Null and output the appropriate message. If the value is indeed Null, then the function must be returned so that no further comparisons can be made:
if (val === null) {
console.log("Value is null");
return;
}
Here, you are comparing val to Null and outputting the appropriate message. If the value is indeed Null, then the function must be returned so that no further comparisons can be made.
- If the value is not Null, then you can safely return the type of the value itself:
console.log("Value is", typeof val);
}
console.log(...) will output however many values are passed into it and concatenate them onto the same line. Here, you output the generic message but then concatenate it with the type of the variable. Since no value is required to be passed from this function, and as there is no more logic to perform, no return statement is required to close out the function.
- To test this function, execute it in the console with different values:
printType(12);
printType("I am a string");
printType({});
printType(null);
The preceding code will result in the following output:
Value is number
Value is string
Value is object
Value is null

Figure 5.4: Exercise 5.02 output
The function you have just created is rather light in terms of introspection. It essentially enables you to determine the general type of a passed in value, but it isn't powerful enough to differentiate object types, including JavaScript's built-in objects. Whether you pass in a Date or an Array, you will get the same output.
You will discover how to be more thorough in determining data types later in this module.