- Getting started with Javascript
JavaScript is a programming language that is used to make web pages interactive. It is a scripting language that is used to create and control dynamic website content, i.e. anything that moves, refreshes, or otherwise changes on your screen without requiring you to manually reload a web page.
To use JavaScript, you need to have a JavaScript engine installed in your browser. All modern browsers have a JavaScript engine built-in. You can also use JavaScript on the server-side using Node.js.
To install Node.js, go to nodejs.org and download the latest version for your operating system.
Once installed, you can run JavaScript files using the node
command.
node myscript.js
- Number
- String
- Boolean
- undefined (Non initialized variables have this value by default)
- null
In JavaScript, all variables are declared using the let
and const
keywords. There is a difference between them, but for now, we will use let
for all variables.
(There is also a var
keyword, but it is not recommended to use it)
The variables data type is determined by the value assigned to it, and can be changed at any time. This means that JavaScript is dynamically typed.
let myNumber = 5;
console.log(typeof myNumber); // number
Type of an undefined variable is also undefined and the value is also undefined.
Type of a null-assigned variable is an object.
let myAge;
console.log(myAge); // undefined
console.log(typeof myAge); // undefined
let myName = null;
console.log(myName); // null
console.log(typeof myName); // object
Template strings are used to create strings that include variables using substitution.
`string text ${expression} string text`;
JavaScript has three reference data types: Array, Object, Function They are all objects under the hood.
The syntax of reference types called object literal syntax.
let car = {
name: "BMW",
model: "X5",
year: 2019,
isUsed: true,
};
You can access the object properties using the dot notation or the bracket notation.
console.log(car.name); // BMW
console.log(car["model"]); // X5
Arrays are used to store multiple values in a single variable.
let fruits = ["apple", "banana", "orange"];
console.log(fruits[0]); // apple
console.log(fruits[1]); // banana
fruits[2] = "grape";
console.log(fruits[2]); // grape
A method is a function that is a property of an object.
let car = {
name: "BMW",
model: "X5",
year: 2019,
isUsed: true,
drive: function () {
console.log("Driving...");
},
};
A function is a piece of code that is called by name. It can be passed data to operate on (i.e. the parameters) and can optionally return data (the return value).
function sum(a, b) {
return a + b;
}
// Function declaration
function sum(a, b) {
return a + b;
}
// Function expression
let sum = function (a, b) {
return a + b;
};
Arrow functions are a short syntax for writing function expressions.
let sum = (a, b) => {
return a + b;
};
If the function has only one statement, and the statement returns a value, you can remove the brackets and the return keyword.
let sum = (a, b) => a + b;
Anonymous functions are functions that are dynamically declared at runtime.
let sum = function (a, b) {
return a + b;
};
An IIFE is a JavaScript function that runs as soon as it is defined.
(function () {
console.log("Hello World!");
})();
let age = 18;
if (age >= 18) {
console.log("You can drive");
} else if (age >= 16 && age < 18) {
console.log("You can drive with supervision");
} else {
console.log("You can't drive");
}
let day = 3;
switch (day) {
case 1:
console.log("Monday");
break;
case 2:
console.log("Tuesday");
break;
case 3:
console.log("Wednesday");
break;
case 4:
console.log("Thursday");
break;
case 5:
console.log("Friday");
break;
case 6:
console.log("Saturday");
break;
case 7:
console.log("Sunday");
break;
default:
console.log("Invalid day");
}
let age = 18;
age >= 18 ? console.log("You can drive") : console.log("You can't drive");
In JavaScript values evaluate to true or false when evaluated in a boolean context.
Falsy values:
- false
- 0
- null
- undefined
All other values are truthy.
for (let i = 0; i < 10; i++) {
console.log(i);
}
let car = {
name: "BMW",
model: "X5",
year: 2019,
isUsed: true,
};
for (let key in car) {
console.log(key, car[key]);
}
let fruits = ["apple", "banana", "orange"];
for (let fruit of fruits) {
console.log(fruit);
}
let i = 0;
while (i < 10) {
console.log(i);
i++;
}
let i = 0;
do {
console.log(i);
i++;
} while (i < 10);
- In a method,
this
refers to the owner object. - Alone,
this
refers to the global object. - In a function,
this
refers to the global object. - In a function, in strict mode,
this
is undefined. - In an event
this
refers to the element that received the event. - Methods like call(), and apply() can refer
this
to any object. - In arrow functions, there is no
this
binding.
Objects are used to model real-world objects that we want to represent inside our programs, and/or provide a simple way to access functionality that would otherwise be hard or impossible to make use of.
Objects are mutable, and they are manipulated by reference, and not by value.
If a car
is an object, then x
and car
are pointing to the same object, and any changes to x
will also change car
. This will not create a copy of car
.
const x = car; // will not create a copy of car
let car = {
name: "BMW",
model: "X5",
year: 2019,
isUsed: true,
get fullName() {
return `${this.name} ${this.model}`;
},
set fullName(value) {
const parts = value.split(" ");
this.name = parts[0];
this.model = parts[1];
},
};
car.fullName = "Mercedes Benz C200";
console.log(car.fullName); // Mercedes Benz
function Car(name, model, year, isUsed) {
this.name = name;
this.model = model;
this.year = year;
this.isUsed = isUsed;
this.drive = function () {
console.log("Driving...");
};
}
let car = new Car("BMW", "X5", 2019, true);
The JavaScript prototype property allows you to add new properties to object constructors:
function Car(name, model, year, isUsed) {
this.name = name;
this.model = model;
this.year = year;
this.isUsed = isUsed;
}
Car.prototype.drive = function () {
console.log("Driving...");
};
class Car {
constructor(name, model, year, isUsed) {
this.name = name;
this.model = model;
this.year = year;
this.isUsed = isUsed;
}
drive() {
console.log("Driving...");
}
}
A promise is an object that may produce a single value some time in the future: either a resolved value, or a reason that it’s not resolved (e.g., a network error occurred). A promise may be in one of 3 possible states: fulfilled, rejected, or pending.
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Success");
// reject(new Error("Error"));
}, 2000);
});
promise
.then((result) => console.log(result))
.catch((err) => console.log(err.message));
If the job is finished successfully, resolve(value)
is called with value
being the result of the job.
If an error occurs, reject(error)
is called with error
being the error object.
The async
keyword is added to functions to tell them to return a promise rather than directly returning the value.
The await
keyword is added before a function call to tell the program to wait for the promise to resolve before continuing.
function getUser(id) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("Reading a user from a database...");
resolve({ id: id, username: "john" });
}, 2000);
});
}
function getRepositories(username) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("Calling GitHub API...");
resolve(["repo1", "repo2", "repo3"]);
}, 2000);
});
}
function getCommits(repo) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("Calling GitHub API...");
resolve(["commit1", "commit2", "commit3"]);
}, 2000);
});
}
async function displayCommits() {
try {
const user = await getUser(1);
const repos = await getRepositories(user.username);
const commits = await getCommits(repos[0]);
console.log(commits);
} catch (err) {
console.log(err.message);
}
}
displayCommits();
The try...catch
statement marks a block of statements to try and specifies a response should an exception be thrown.
try {
// code to try
} catch (err) {
// code to handle errors
}
You can use finally
to execute code, after try and catch, regardless of the result:
try {
// code to try
} catch (err) {
// code to handle errors
} finally {
// code to be executed regardless of the try / catch result
}
You can use throw
to create custom errors:
try {
// code to try
throw new Error("Error message");
} catch (err) {
// code to handle errors
}
Combined with async/await:
async function displayCommits() {
try {
const user = await getUser(1);
const repos = await getRepositories(user.username);
const commits = await getCommits(repos[0]);
console.log(commits);
} catch (err) {
console.log(err.message);
}
}
A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action.
function getUser(id, callback) {
setTimeout(() => {
console.log("Reading a user from a database...");
callback({ id: id, username: "john" });
}, 2000);
}
function getRepositories(username, callback) {
setTimeout(() => {
console.log("Calling GitHub API...");
callback(["repo1", "repo2", "repo3"]);
}, 2000);
}
function getCommits(repo, callback) {
setTimeout(() => {
console.log("Calling GitHub API...");
callback(["commit1", "commit2", "commit3"]);
}, 2000);
}
getUser(1, (user) => {
console.log(user);
getRepositories(user.username, (repos) => {
console.log(repos);
getCommits(repos[0], (commits) => {
console.log(commits);
});
});
});
Strict mode is a way to introduce better error-checking into your code.
// Whole-script strict mode syntax
"use strict";
// Function-level strict mode syntax
function strict() {
"use strict";
// function body
}