034.2 Lesson 1
Certificate: |
Web Development Essentials |
---|---|
Version: |
1.0 |
Topic: |
034 JavaScript Programming |
Objective: |
034.2 JavaScript Data Structures |
Lesson: |
1 of 1 |
Introduction
Programming languages, like natural languages, represent reality through symbols that are combined into meaningful statements. The reality represented by a programming language is the machine’s resources, such as processor operations, devices, and memory.
Each of the myriad programming languages adopts a paradigm for representing information. JavaScript adopts conventions typical of high-level languages, where most of details such as memory allocation are implicit, allowing the programmer to focus on the script’s purpose in the context of the application.
High-Level Languages
High-level languages provide abstract rules so that the programmer needs to write less code to express an idea. JavaScript offers convenient ways to make use of computer memory, using programming concepts that simplify the writing of recurring practices and that are generally sufficient for the web developer’s purpose.
Note
|
Although it’s possible to use specialized mechanisms for meticulous memory access, the simpler types of data we’ll look at are more general in use. |
Typical operations in a web application consist of requesting data through some JavaScript instruction and storing it to be processed and eventually presented to the user. This storage is quite flexible in JavaScript, with suitable storage formats for each purpose.
Declaration of Constants and Variables
The declaration of constants and variables to hold data is the cornerstone of any programming language. JavaScript adopts the convention of most programming languages, assigning values to constants or variables with the name = value
syntax. The constant or variable on the left takes the value on the right. The constant or variable name must start with a letter or underscore.
The type of data stored in the variable does not need to be indicated, because JavaScript is a dynamic typing language. The type of the variable is inferred from the value assigned to it. However, it is convenient to designate certain attributes in the declaration to guarantee the expected result.
Note
|
TypeScript is a JavaScript-inspired language that, like lower-level languages, allows you to declare variables for specific types of data. |
Constants
A constant is a symbol that is assigned once when the program starts and never changes. Constants are useful to specify fixed values such as defining the constant PI
to be 3.14159265, or COMPANY_NAME
to hold the name of your company.
In a web application, for example, take a client that receives weather information from a remote server. The programmer may decide that the address to the server must be constant, because it will not change during the application’s execution. The temperature information, however, can change with every new data arrival from the server.
The interval between queries made to the server can also be defined as a constant, which can be queried from any part of the program:
const update_interval = 10;
function setup_app(){
console.log("Update every " + update_interval + "minutes");
}
When invoked, the setup_app()
function displays the message Update every 10 minutes
message on the console. The term const
placed before the name update_interval
makes sure that its value will remain the same throughout the entire execution of the script. If an attempt is made to reset the value of a constant, a TypeError: Assignment to constant variable
error is issued.
Variables
Without the term const
, JavaScript automatically assumes that update_interval
is a variable and that its value can be modified. This is equivalent to declaring the variable explicitly with var
:
var update_interval;
update_interval = 10;
function setup_app(){
console.log("Update every " + update_interval + "minutes");
}
Note that although the update_interval
variable was defined outside the function, it was accessed from within the function. Any constant or variable declared outside of functions or code blocks defined by braces ({}
) has global scope; that is, it can be accessed from any part of the code. The opposite is not true: a constant or variable declared inside a function has local scope, so it is accessible only from inside the function itself. Bracket-delimited code blocks, such as those placed in if
decision structures or for
loops, delimit the scope of constants, but not variables declared as var
. The following code, for example, is valid:
var success = true;
if ( success == true )
{
var message = "Transaction succeeded";
var retry = 0;
}
else
{
var message = "Transaction failed";
var retry = 1;
}
console.log(message);
The console.log(message)
statement is able to access the message
variable, even though it has been declared within the code block of the if
structure. The same would not happen if message
were constant, as exemplified in the following example:
var success = true;
if ( success == true )
{
const message = "Transaction succeeded";
var retry = 0;
}
else
{
const message = "Transaction failed";
var retry = 1;
}
console.log(message);
In this case, an error message of type ReferenceError: message is not defined
would be issued and the script would be stopped. While it may seem like a limitation, restricting the scope of variables and constants helps to avoid confusion between the information processed in the script body and in its different code blocks. For this reason, variables declared with let
instead of var
are also restricted in scope by the blocks delimited by braces. There are other subtle differences between declaring a variable with var
or with let
, but the most significant of these concerns the scope of the variable, as discussed here.
Types of Values
Most of the time, the programmer doesn’t need to worry about the type of data stored in a variable, because JavaScript automatically identifies it with one of its primitive types during the first assignment of a value to the variable. Some operations, however, can be specific to one data type or another and can result in errors when used without discretion. In addition, JavaScript offers structured types that allow you to combine more than one primitive type into a single object.
Primitive Types
Primitive type instances correspond to traditional variables, which store only one value. Types are defined implicitly, so the typeof
operator can be used to identify what type of value is stored in a variable:
console.log("Undefined variables are of type", typeof variable);
{
let variable = true;
console.log("Value `true` is of type " + typeof variable);
}
{
let variable = 3.14159265;
console.log("Value `3.14159265` is of type " + typeof variable);
}
{
let variable = "Text content";
console.log("Value `Text content` is of type " + typeof variable);
}
{
let variable = Symbol();
console.log("A symbol is of type " + typeof variable);
}
This script will display on the console what type of variable was used in each case:
undefined variables are of type undefined Value `true` is of type boolean Value `3.114159265` is of type number Value `Text content` is of type string A symbol is of type symbol
Notice that the first line tries to find the type of an undeclared variable. This causes the given variable to be identified as undefined
. The symbol
type is the least intuitive primitive. Its purpose is to provide a unique attribute name within an object when there is no need to define a specific attribute name. An object is one of the data structures we’ll look at next.
Structured Types
While primitive types are sufficient for writing simple routines, there are drawbacks to using them exclusively in more complex applications. An e-commerce application, for example, would be much more difficult to write, because the programmer would need to find ways to store lists of items and corresponding values using only variables with primitive types.
Structured types simplify the task of grouping information of the same nature into a single variable. A list of items in a shopping cart, for instance, can be stored in a single variable of type array:
let cart = ['Milk', 'Bread', 'Eggs'];
As demonstrated in the example, an array of items is designated with square brackets. The example has populated the array with three literal string values, hence the use of single quotes. Variables can also be used as items in an array, but in that case they must be designated without quotes. The number of items in an array can be queried with the length
property:
let cart = ['Milk', 'Bread', 'Eggs'];
console.log(cart.length);
The number 3
will be displayed in the console output. New items can be added to the array with the push()
method:
cart.push('Candy');
console.log(cart.length);
This time, the amount displayed will be 4
. Each item in the list can be accessed by its numeric index, starting with 0
:
console.log(cart[0]);
console.log(cart[3]);
The output displayed on the console will be:
Milk Candy
Just as you can use push()
to add an element, you can use pop()
to remove the last element from an array.
Values stored in an array do not need be of the same type. It is possible, for example, to store the quantity of each item beside it. A shopping list like the one in the previous example could be constructed as follows:
let cart = ['Milk', 1, 'Bread', 4, 'Eggs', 12, 'Candy', 2];
// Item indexes are even
let item = 2;
// Quantities indexes are odd
let quantity = 3;
console.log("Item: " + cart[item]);
console.log("Quantity: " + cart[quantity]);
The output displayed on the console after running this code is:
Item: Bread Quantity: 4
As you may have already noticed, combining the names of items with their respective quantities in a single array may not be a good idea, because the relationship between them is not explicit in the data structure and is very susceptible to (human) errors. Even if an array were used for names and another array for quantities, maintaining the integrity of the list would require the same care and would not be very productive. In these situations, the best alternative is to use a more appropriate data structure: an object.
In JavaScript, an object-type data structure lets you bind properties to a variable. Also, unlike an array, the elements that make up an object do not have a fixed order. A shopping list item, for example, can be an object with the properties name
and quantity
:
let item = { name: 'Milk', quantity: 1 };
console.log("Item: " + item.name);
console.log("Quantity: " + item.quantity);
This example shows that an object can be defined using braces ({}
), where each property/value pair is separated by a colon and the properties are separated by commas. The property is accessible in the format variable.property, as in item.name
, both for reading and for assigning new values. The output displayed on the console after running this code is:
Item: Milk Quantity: 1
Finally, each object representing an item can be included in the shopping list array. This can be done directly when creating the list:
let cart = [{ name: 'Milk', quantity: 1 }, { name: 'Bread', quantity: 4 }];
As before, a new object representing an item can be added later to the array:
cart.push({ name: 'Eggs', quantity: 12 });
Items in the list are now accessed by their index and their property name:
console.log("Third item: " + cart[2].name);
console.log(cart[2].name + " quantity: " + cart[2].quantity);
The output displayed on the console after running this code is:
third item: eggs Eggs quantity: 12
Data structures allow the programmer to keep their code much more organized and easier to maintain, whether by the original author or by other programmers on the team. Also, many outputs from JavaScript functions are in structured types, which need to be handled properly by the programmer.
Operators
So far, we’ve pretty much seen only how to assign values to newly created variables. As simple as it is, any program will perform several other manipulations on the values of variables. JavaScript offers several types of operators that can act directly on the value of a variable or store the result of the operation in a new variable.
Most operators are geared toward arithmetic operations. To increase the quantity of an item in the shopping list, for example, just use the +
addition operator:
item.quantity = item.quantity + 1;
The following snippet prints the value of item.quantity
before and after the addition. Do not mix up the roles of the plus sign in the snippet. The console.log
statements use a plus sign to combine two strings.
let item = { name: 'Milk', quantity: 1 };
console.log("Item: " + item.name);
console.log("Quantity: " + item.quantity);
item.quantity = item.quantity + 1;
console.log("New quantity: " + item.quantity);
The output displayed on the console after running this code is:
Item: Milk Quantity: 1 New quantity: 2
Note that the value previously stored in item.quantity
is used as the operand of the addition operation: item.quantity = item.quantity + 1
. Only after the operation is complete the value in item.quantity
is updated with the result of the operation. This kind of arithmetic operation involving the current value of the target variable is quite common, so there are shorthand operators that allow you to write the same operation in a reduced format:
item.quantity += 1;
The other basic operations also have equivalent shorthand operators:
-
a = a - b
is equivalent toa -= b
. -
a = a * b
is equivalent toa *= b
. -
a = a / b
is equivalent toa /= b
.
For addition and subtraction, there is a third format available when the second operand is only one unit:
-
a = a + 1
is equivalent toa++
. -
a = a - 1
is equivalent toa--
.
More than one operator can be combined in the same operation and the result can be stored in a new variable. For example, the following statement calculates the total price of an item plus a shipping cost:
let total = item.quantity * 9.99 + 3.15;
The order in which the operations are carried out follows the traditional order of precedence: first the multiplication and division operations are carried out, and only then are the addition and subtraction operations carried out. Operators with the same precedence are executed in the order they appear in the expression, from left to right. To override the default precedence order, you can use parentheses, as in a * (b + c)
.
In some situations, the result of an operation doesn’t even need to be stored in a variable. This is the case when you want to evaluate the result of an expression within an if
statement:
if ( item.quantiy % 2 == 0 )
{
console.log("Quantity for the item is even");
}
else
{
console.log("Quantity for the item is odd");
}
The %
(modulo) operator returns the remainder of the division of the first operand by the second operand. In the example, the if
statement checks whether the remainder of the division of item.quantity
by 2
is equal to zero, that is, whether item.quantity
is a multiple of 2.
When one of the operands of the +
operator is a string, the other operators are coerced into strings and the result is a concatenation of strings. In the previous examples, this type of operation was used to concatenate strings and variables into the argument of the console.log
statement.
This automatic conversion might not be the desired behavior. A user-supplied value in a form field, for example, might be identified as a string, but it is actually a numeric value. In cases like this, the variable must first be converted to a number with the Number()
function:
sum = Number(value1) + value2;
Moreover, it is important to verify that the user has provided a valid value before proceeding with the operation. In JavaScript, a variable without an assigned value contains the value null
. This allows the programmer to use a decision statement such as if ( value1 == null )
to check whether a variable was assigned a value, regardless of the type of the value assigned to the variable.
Guided Excercises
-
An array is a data structure present in several programming languages, some of which allow only arrays with items of the same type. In the case of JavaScript, is it possible to define an array with items of different types?
-
Based on the example
let item = { name: 'Milk', quantity: 1 }
for an object in a shopping list, how could this object be declared to include the price of the item? -
In a single line of code, what are the ways to update a variable’s value to half its current value?
Explorational Excercises
-
In the following code, what value will be displayed in the console output?
var value = "Global"; { value = "Location"; } console.log(value);
-
What will happen when one or more of the operands involved in a multiplication operation is a string?
-
How is it possible to remove the
Eggs
item from thecart
array declared withlet cart = ['Milk', 'Bread', 'Eggs']
?
Summary
This lesson covers the basic use of constants and variables in JavaScript. JavaScript is a dynamic typing language, so the programmer doesn’t need to specify the variable type before setting it. However, it is important to know the language’s primitive types to ensure the correct outcome of basic operations. Furthermore, data structures such as arrays and objects combine primitive types and allow the programmer to build more complex, composite variables. This lesson goes through the following concepts and procedures:
-
Understanding constants and variables
-
Variable scope
-
Declaring variables with
var
andlet
-
Primitive types
-
Arithmetic operators
-
Arrays and objects
-
Type coercion and conversion
Answers to Guided Exercises
-
An array is a data structure present in several programming languages, some of which allow only arrays with items of the same type. In the case of JavaScript, is it possible to define an array with items of different types?
Yes, in JavaScript it is possible to define arrays with items of different primitive types, such as strings and numbers.
-
Based on the example
let item = { name: 'Milk', quantity: 1 }
for an object in a shopping list, how could this object be declared to include the price of the item?let item = { name: 'Milk', quantity: 1, price: 4.99 };
-
In a single line of code, what are the ways to update a variable’s value to half its current value?
One can use the variable itself as an operand,
value = value / 2
, or the shorthand operator/=
:value /= 2
.
Answers to Explorational Exercises
-
In the following code, what value will be displayed in the console output?
var value = "Global"; { value = "Location"; } console.log(value);
Location
-
What will happen when one or more of the operands involved in a multiplication operation is a string?
JavaScript will assign the value
NaN
(Not a Number) to the result, indicating that the operation is invalid. -
How is it possible to remove the
Eggs
item from thecart
array declared withlet cart = ['Milk', 'Bread', 'Eggs']
?Arrays in javascript have the
pop()
method, which removes the last item in the list:cart.pop()
.