JavaScript Course 1: Basics
References
- Code with Mosh: The Ultimate JavaScript Mastery Series – Part 1
- W3School: JavaScript Tutorial
- ECMAScript 6
Variables and Constants
var variableName = ''; // Before ECMAScript 6
let variableName = ''; // After ECMAScript 6
const constName = 'ABC'; // After ECMAScript 6
Naming conventions, rules:
- Names cannot be a reserved keyword;
- They should be meaningful;
- Cannot start with a number;
- Cannot contain space or hyphen.;
- The names are case sensitive;
- Use
camelNotations
;
Define multiple variables or constants:
let firstName, lastName;
let firstName = 'Spas', lastName = 'Spasov';
// Best practice is to declare each variable separately:
let firstName = 'Spas';
let lastName = 'Spasov';
Scope (summary from all parts of the course)
Read this section once again when finish the course. JavaScript variables can belong to the local or global scope. Global variables live until the page is discarded, like when you navigate to another page or close the window. Local variables have short lives. They are created when the function (or other type of code block) is invoked, and deleted when the function is finished.
Variables created without a declaration keyword (var
, let
, or const
) are always global, even if they are created inside a function (or other type of code block).
A local scope is defined by the JavaScript elements that uses code block – {}
, like as:
- Functions:
function() {…}
- Loops:
while() {…}
,for() {…}
, etc. - Objects: const
obj = {…}
- If blocks:
if (…) {…}
- etc.
{
const message = 'hi';
}
console.log(message);
Uncaught ReferenceError: message is not defined at <anonymous>:1:13
Global variables can be made local (private) with closures.
It is better practice, when it is possible, to do not use Global variables.
When we have Local and Global variables (or constants) with exact same names – the Local variables (or constants) take precedence over the global variables (or constants).
Var vs Let and Const (issues with Var)
Read this section once again when finish the course.
Issue 1
The first issue with var
is that, it creates function scope, while let
(and const
) creates block scope. So the variables created by var
can be accessed outside of the scope where they are defined.
function start() {
for (let i = 0; i < 2; i++)
console.log(i);
console.log(i);
}
start();
0
1
Uncaught ReferenceError: i is not defined
at start (<anonymous>:5:17)
at <anonymous>:1:1
function start() {
for (var i = 0; i < 2; i++)
console.log(i);
console.log(i);
}
start(); // In the output below you can see the 'var i' is not terminated when the 'for(...){...}'' block is finished
0
1
2
Another example how var
is accessible from outside the block where it is defined.
function start() {
for (let i = 0; i < 5; i++) {
if (true) {
var color = 'red';
}
}
console.log(color);
}
start();
red
If we have used let color = 'red'
the above code will throw an error, but when we use var color = 'red'
we can access the variable inside the whole function not only within the if(…){…}
scope.
Issue 2
The second issue with var
is related to the Global and the Local Scope – the variables, defined by var
are attached to the window
object (used by the browsers at the frontend).
var firstName = 'John';
let lastName = 'Smith';
console.log(window.firstName, window.lastName);
John undefined
Types
- Primitives (value types)
- Reference types (objects, arrays, functions)
JavaScript is a dynamic language. Which means we can change the type of a variable during the script, unlike the static languages where the defined variable type is constant and cannot be changed during the program.
Primitive types
The primitive types in JavaScript are:
- Strings
- Numbers
- Booleans
- undefined
- null
- Symbol
let name = 'Spas'; // String Literal
let age = 55; // Number Literal
let isViewMode = true; // Boolean Literal (true/false)
let fullName = undefined; // This is the default type of values in JavaScript
let lastName = null;
let mySymbol = Symbol('someDescription'); // Symbol value with description
The Numbers could be integer or floating point numbers, but their types are all numbers.
let integer = 12;
typeof integer; // "number"
let floating = 1.2;
typeof floating; // "number"
Reference types
The reference types in JavaScript are:
- Objects
- Arrays
- Functions
Objects
The Objects has:
- Properties – primitives defined by
"keys":
and"values",
- Methods – internal
functions()
that operates with the properties of the object.
let person = {}; // Object Literal
typeof person; // "object"
let person = {
"name": "Spas",
"age": 55
};
console.log(person);
{name: "Spas", age: 55}
We can access the Properties of an Object via:
- Dot notation:
object.proprtyName
- Bracket notation:
object['proprtyName']
person.name = "Ivan"; // Assing a value to an object property via Dot notatin
person['age'] = 25; // Assing a value to an object property via Bracket notatin
console.log(person);
{name: "Ivan", age: 25}
Using Dot notation is cleaner and easier, but the Bracket notation could be used when we want to pass variable in the place of the key – i.e. when when using a loop or so.
let keyToPrint = 'name';
console.log(person[keyToPrint]);
Ivan
Arrays
JavaScript Array is a data structure that we use to represent a list of items, in this count an item could be Primitives or Objects. JavaScript Arrays cannot be multi dimensional, but the can store Objects instead Primitives – and can mix them.
let selectedItems = []; // Array Literal
typeof selectedItems; // "object"
The JavaScript Array is (a kind of) Object and it has properties and methods (inherited from its Prototype). See the selectedItems.lenght
example below.
let selectedItems = ['red', 'blue'];
console.log(selectedItems);
(2) ["red", "blue"]
console.log(selectedItems.length)
2
Each element of an Array has an Index. The Array Index starts from 0
. So the first element has index 0
, the second element has index 1
and so on.
console.log(selectedItems[0], selectedItems[1]);
red blue
The JavaScript Array length is dynamic – we can change it. We can create a new index element and assign a value in the following way:
selectedItems[2] = 'green'; // String
selectedItems[3] = 33; // Number
selectedItems[4] = {}; // Object
Note in this example we have mixed the element types.
console.log(selectedItems);
(5) ["red", "blue", "green", 33, {…}]
Functions
JavaScript Functions are sets of statements that performs a task or calculates a value. The Functions could have Inputs – could use (multiple) parameters – but it is not mandatory.
function greet(parameter) {
/** Body of the function **/
}
typeof greet; // "function"
function greet(name) { // 'name' is an input parameter of the function
console.log('Hello ' + name);
}
greet('Nik'); // 'Nik' is an argument which become a value of the param. 'name'
Hello Nik
The functions could Change the values of a global variables (objects) or could Return a value.
function square(number) {
return number * number;
}
The returned value could be assigned to a variable or object property.
let result = square(2);
console.log(result);
4
Single responsibility principle. According to this principle we should have functions that are small and focused only on one thing. Let's say we have a function that calculate the average grade of a student.
const marks = [80, 90, 90];
function calculateGrade(marks) {
let sum = 0;
for (let mark of marks) sum += mark;
let averageGrade = sum / marks.length;
if (averageGrade < 60) return 'F';
if (averageGrade < 70) return 'D';
if (averageGrade < 80) return 'C';
if (averageGrade < 90) return 'B';
return 'A';
}
console.log(calculateGrade(marks));
B
By applying the Single responsibility principle we will have two small functions, one generic function that will calculate the average value, and one other function that will map the result.
function calculateGrade(marks) {
let averageGrade = calculateAverage(marks);
if (averageGrade < 60) return 'F';
if (averageGrade < 70) return 'D';
if (averageGrade < 80) return 'C';
if (averageGrade < 90) return 'B';
return 'A';
}
function calculateAverage(array) {
let sum = 0;
for (let value of array) sum += value;
return sum / array.length;
}
Read also:
Garbage Collector
In low level languages like C or C++, when creating an object we need to allocate memory to it, and when we're done we have to deallocate memory. But in JavaScript we don't have this concept. We can easily create a new object. At the time we initialize this object, then memory is automatically allocated to this object. Next, we can use that. And when we were done using, we don't have to deallocate the memory. So the JavaScript engine has what we call a garbage collector.
The job of the garbage collector is to find the variables or constants that are no longer used and then deallocate the memory that was allocated to them earlier. So you as a JavaScript developer do not have to worry about this memory allocation. And the allocation happens automatically behind the scene and you have no control over that.
You cannot tell the garbage collector when to run and what variables to remove from the memory. So based on some complex algorithms, this garbage collector runs in the background. It figures out what variables are not used and then it will automatically deallocate their memory.