JavaScript basics
Before we start diving into the various data structures and algorithms, let's have a quick overview of the JavaScript language. This section will present the JavaScript basics required to implement the algorithms we will create in the subsequent chapters.
To start, let's see the two different ways we can use JavaScript code in an HTML page:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> </head> <body> <script> alert('Hello, World!'); </script> </body> </html>
The first way is demonstrated by the previous code. We need to create an HTML file and write this code on it. In this example, we are declaring the script
tag inside the HTML file, and inside the script
tag, we have the JavaScript code.
For the second example, we need to create a JavaScript file (we can save it as 01-HelloWorld.js
), and inside this file, we will insert the following code:
alert('Hello, World!');
Then, our HTML file will look like this:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> </head> <body> <script src="01-HelloWorld.js"> </script> </body> </html>
The second example demonstrates how to include a JavaScript file inside an HTML file.
By executing any of these two examples, the output will be the same. However, the second example is the best practice.
Note
You may find JavaScript include
statements or JavaScript code inside the head
tag in some examples on the Internet. As a best practice, we will include any JavaScript code at the end of the body
tag. This way, the HTML will be parsed by the browser and displayed before the scripts are loaded. This boosts the performance of the page.
Variables
Variables store data that can be set, updated, and retrieved whenever needed. Values that are assigned to a variable belong to a type. In JavaScript, the available types are numbers, strings, Booleans, functions, and objects. We also have undefined and null, along with arrays, dates, and regular expressions. The following is an example of how to use variables in JavaScript:
var num = 1; //{1} num = 3; //{2} var price = 1.5; //{3} var name = 'Packt'; //{4} var trueValue = true; //{5} var nullVar = null; //{6} var und; //7
On line {1}
, we have an example of how to declare a variable in JavaScript (we are declaring a number). Although it is not necessary to use the var
keyword declaration, it is a good practice to always specify when we are declaring a new variable.
On line {2}
, we are updating an existing variable. JavaScript is not a strongly-typed language. This means you can declare a variable and initialize it with a number, and then update it with a string or any other data type. Assigning a value to a variable that is different from its original type is also not a good practice.
On line {3}
, we are also declaring a number, but this time it is a decimal floating point. On line {4}
, we are declaring a string; on line {5}
, we are declaring a Boolean. On line {6}
, we are declaring a null
value, and on line {7}
, we are declaring an undefined variable. A null
value means no value and undefined
means a variable that has been declared but not yet assigned a value:
console.log("num: "+ num); console.log("name: "+ name); console.log("trueValue: "+ trueValue); console.log("price: "+ price); console.log("nullVar: "+ nullVar); console.log("und: "+ und);
If we want to see the value of each variable we have declared, we can use console.log
to do so, as listed in the previous code snippet.
Note
We have three ways of outputting values in JavaScript that we can use with the examples of this book. The first one is alert('My text here')
, which will output an alert window on the browser; the second one is console.log('My text here')
, which will output text on the Console tab of the debug tool (Google Developer Tools or Firebug, depending on the browser you are using). Finally, the third way is outputting the value directly on the HTML page that is being rendered by the browser by using document.write('My text here')
. You can use the option that you feel most comfortable with.
The console.log
method also accepts more than just arguments. Instead of console.log("num: "+ num)
, we can also use console.log("num: ", num)
.
We will discuss functions and objects later in this chapter.
Variable scope
Scope refers to where in the algorithm we can access the variable (it can also be a function when we are working with function scopes). There are local and global variables.
Let's look at an example:
var myVariable = 'global'; myOtherVariable = 'global'; function myFunction(){ var myVariable = 'local'; return myVariable; } function myOtherFunction(){ myOtherVariable = 'local'; return myOtherVariable; } console.log(myVariable); //{1} console.log(myFunction()); //{2} console.log(myOtherVariable); //{3} console.log(myOtherFunction()); //{4} console.log(myOtherVariable); //{5}
Line {1}
will output global
because we are referring to a global variable. Line {2}
will output local
because we declared the myVariable
variable inside the myFunction
function as a local variable, so the scope will be inside myFunction
only.
Line {3}
will output global
because we are referencing the global variable named myOtherVariable
that was initialized in the second line of the example. Line {4}
will output local
. Inside the myOtherFunction
function, we are referencing the myOtherVariable
global variable and assigning the value local
to it because we are not declaring the variable using the var
keyword. For this reason, line {5}
will output local
(because we changed the value of the variable inside myOtherFunction
).
You may hear that global variables in JavaScript are evil, and this is true. Usually, the quality of JavaScript source code is measured by the number of global variables and functions (a large number is bad). So, whenever possible, try avoiding global variables.
Operators
We need operators when performing any operation in a programming language. JavaScript also has arithmetic, assignment, comparison, logical, bitwise, and unary operators, among others. Let's take a look at them:
var num = 0; // {1} num = num + 2; num = num * 3; num = num / 2; num++; num--; num += 1; // {2} num -= 2; num *= 3; num /= 2; num %= 3; console.log('num == 1 : ' + (num == 1)); // {3} console.log('num === 1 : ' + (num === 1)); console.log('num != 1 : ' + (num != 1)); console.log('num > 1 : ' + (num > 1)); console.log('num < 1 : ' + (num < 1)); console.log('num >= 1 : ' + (num >= 1)); console.log('num <= 1 : ' + (num <= 1)); console.log('true && false : ' + (true && false)); // {4} console.log('true || false : ' + (true || false)); console.log('!true : ' + (!true));
On line {1}
, we have the arithmetic operators. In the following table, we have the operators and their descriptions:
Arithmetic operator |
Description |
---|---|
|
Addition |
|
Subtraction |
|
Multiplication |
|
Division |
|
Modulus (remainder of a division operation) |
|
Increment |
|
Decrement |
On line {2}
, we have the assignment operators. In the following table, we have the operators and their descriptions:
Assignment operator |
Description |
---|---|
|
Assignment |
|
Addition assignment (x += y) == (x = x + y) |
|
Subtraction assignment (x -= y) == (x = x - y) |
|
Multiplication assignment (x *= y) == (x = x * y) |
|
Division assignment (x /= y) == (x = x / y) |
|
Remainder assignment (x %= y) == (x = x % y) |
On line {3}
, we have the comparison operators. In the following table, we have the operators and their descriptions:
Comparison operator |
Description |
---|---|
|
Equal to |
|
Equal to (value and object type both) |
|
Not equal to |
|
Greater than |
|
Greater than or equal to |
|
Less than |
|
Less than or equal to |
And on line {4}
, we have the logical operators. In the following table, we have the operators and their descriptions:
Logical operator |
Description |
---|---|
|
And |
|
Or |
|
Not |
JavaScript also supports bitwise operators, shown as follows:
console.log('5 & 1:', (5 & 1)); console.log('5 | 1:', (5 | 1)); console.log('~ 5:', (~5)); console.log('5 ^ 1:', (5 ^ 1)); console.log('5 << 1:', (5 << 1)); console.log('5 >> 1:', (5 >> 1));
The following table contains more detailed descriptions of the bitwise operators:
Bitwise operator |
Description |
---|---|
& |
And |
| |
Or |
~ |
Not |
^ |
Xor |
<< |
Left shift |
>> |
Right shift |
The typeof
operator returns the type of the variable or expression. For example, have a look at the following code:
console.log('typeof num:', typeof num); console.log('typeof Packt:', typeof 'Packt'); console.log('typeof true:', typeof true); console.log('typeof [1,2,3]:', typeof [1,2,3]); console.log('typeof {name:John}:', typeof {name:'John'});
The output will be as follows:
typeof num: number typeof Packt: string typeof true: boolean typeof [1,2,3]: object typeof {name:John}: object
JavaScript also supports the delete
operator, which deletes a property from an object:
var myObj = {name: 'John', age: 21}; delete myObj.age; console.log(myObj); //outputs Object {name: "John"}
In this book's algorithms, we will be using some of these operators.
Truthy and falsy
In JavaScript, true and false are a little bit tricky. In most languages, the Boolean values true
and false
represent the true/false results. In JavaScript, a string suchas "Packt" has the value true
, for example.
The following table can help us better understand how true
and false
work in JavaScript:
Value type |
Result |
---|---|
|
|
|
|
|
true is |
|
The result is |
|
The result is |
|
|
Let's see some examples and verify their output:
function testTruthy(val){ return val ? console.log('truthy') : console.log('falsy'); } testTruthy(true); //true testTruthy(false); //false testTruthy(new Boolean(false)); //true (object is always true) testTruthy(''); //false testTruthy('Packt'); //true testTruthy(new String('')); //true (object is always true) testTruthy(1); //true testTruthy(-1); //true testTruthy(NaN); //false testTruthy(new Number(NaN)); //true (object is always true) testTruthy({}); //true (object is always true) var obj = {name:'John'}; testTruthy(obj); //true testTruthy(obj.name); //true testTruthy(obj.age); //false (age does not exist)
The equals operators (== and ===)
The two equals operators supported by JavaScript can cause a little bit of confusion when working with them.
When using ==
, values can be considered equal even when they are of different types. This can be confusing even for a senior JavaScript developer. Let's analyze how ==
works using the following table:
Type(x) |
Type(y) |
Result |
---|---|---|
|
|
|
|
|
true |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
If x and y are the same type, then JavaScript will use the equals method to compare the two values or objects. Any other combination that is not listed in the table gives a false result.
The toNumber
and toPrimitive
methods are internal and evaluate the values according to the tables that follow.
The toNumber
method is presented here:
Value type |
Result |
---|---|
|
|
|
+0. |
|
If the value is |
|
The value of the number. |
|
This parses the string into a number. If the string consists of alphabetical characters, the result is NaN; if the string consists of numbers, it is transformed into a number. |
|
|
And toPrimitive
is presented here:
Value type |
Result |
---|---|
|
If |
Let's verify the results of some examples. First, we know that the output of the following code is true (string length > 1):
console.log('packt' ? true : false);
Now, what about the following code? Let's see:
console.log('packt' == true);
The output is false! Let's understand why:
- First, it converts the Boolean value using
toNumber
, so we havepackt == 1
. - Then, it converts the string value using
toNumber
. As the string consists of alphabetical characters, it returns NaN, so we haveNaN == 1
, which is false.
And what about the following code? Let's see:
console.log('packt' == false);
The output is also false! The following are the steps:
- First, it converts the Boolean value using
toNumber
, so we havepackt == 0
. - Then, it converts the string value using
toNumber
. As the string consists of alphabetical characters, it returns NaN, so we haveNaN == 0
, which is false.
And what about the operator ===
? It is much easier. If we are comparing two values of different types, the result is always false. If they have the same type, they are compared according to the following table:
Type(x) |
Values |
Result |
---|---|---|
|
x has the same value as y (but not NaN) |
true |
|
x and y are identical characters |
true |
|
x and y are both true or both false |
true |
|
x and y reference the same object |
true |
If x and y are different types, then the result is false.
Let's see some examples:
console.log('packt' === true); //false console.log('packt' === 'packt'); //true var person1 = {name:'John'}; var person2 = {name:'John'}; console.log(person1 === person2); //false, different objects