Backend Basics
Backend Basics
In JavaScript, let, var, and const are used to declare variables, but they have some
differences in terms of scope, hoisting, and reassignment.
1.1.1 Scope:
Scope refers to the visibility and accessibility of variables and functions within a program.
● In JavaScript, variables have either global scope, function scope (if declared with
var), or block scope (if declared with let or const).
● Global scope means the variable is accessible throughout the entire program.
● Function scope means the variable is accessible only within the function in which it is
declared.
● Block scope means the variable is accessible only within the block (enclosed by curly
braces) in which it is declared.
Function Scope:
● Variables declared with var have function scope. This means they are accessible
throughout the entire function in which they are declared, including any nested blocks
within that function.
● Function scope limits the visibility of variables to the function in which they are
defined. Variables declared within a function are not accessible outside of that
function.
● example:
function exampleFunction() {
console.log(x); // Output: 10
}
console.log(x); // Error: x is not defined
Further:
JavaScript has function scope: Each function creates a new scope.
Variables defined inside a function are not accessible (visible) from outside the function.
Variables declared with var, let and const are quite similar when declared inside a function.
Block Scope:
● Variables declared with let and const have block scope. This means they are only
accessible within the block (enclosed by curly braces) in which they are declared.
● Block scope limits the visibility of variables to the block in which they are defined.
Variables declared within a block are not accessible outside of that block.
● Here's an example:
if (true) {
console.log(y); // Output: 20
Further:
Variables declared inside a { } block cannot be accessed from outside the block:
{
let x = 2;
}
// x can NOT be used here
Variables declared with the var keyword can NOT have block scope.
Variables declared inside a { } block can be accessed from outside the block.
Example
{
var x = 2;
}
// x CAN be used here
Or
{
let x = 10; // x is block-scoped
console.log(x); // Output: 10
}
// Attempting to access x outside the block will result in an error
console.log(x); // Error: x is not defined
Local Scope
Example
function myFunction() {
let carName = "Volvo";
// code here CAN use carName
}
Local variables have Function Scope:They can only be accessed from within the
function.Since local variables are only recognized inside their functions, variables with the
same name can be used in different functions.Local variables are created when a function
starts, and deleted when the function is completed.
Global Scope
1.1.2 Hoisting:
1.1.3 Reassignment:
● Reassignment refers to the act of assigning a new value to an existing variable.
● In JavaScript, you can reassign values to variables declared with var, let, or const,
but with some differences:
○ Variables declared with var can be reassigned and redeclared within the
same scope.
○ Variables declared with let can be reassigned but not redeclared within the
same scope.
○ Variables declared with const cannot be reassigned or redeclared within the
same scope, but they can be mutated if they hold a reference to a mutable
object (e.g., an array or object).
2. let:
○ Variables declared with let are block-scoped. This means they are only
accessible within the block (enclosed by curly braces) in which they are
declared.
○ let variables are not hoisted to the top of their containing block. They are
hoisted to the top of the block scope, but they are in a "temporal dead zone"
until the actual declaration is encountered.
○ You can reassign values to let variables, but you cannot redeclare them in the
same scope.
3. const:
○ Variables declared with const are also block-scoped.
○ Unlike var and let, you must initialize a const variable when it's declared, and
once initialized, its value cannot be changed.
○ Similar to let, const variables are not hoisted to the top of their containing
block and are also in the temporal dead zone until the actual declaration is
encountered.
Summary,
Use var if you need function scope or if you're working with older JavaScript code.
Use let for block-scoped variables that may change their value.
Use const for variables that should not be reassigned.
1.2 Loops in JavaScript
Syntax:
for (initialization; condition; increment/decrement) {
// code block to be executed
}
Example:
for (let i = 0; i < 5; i++) {
console.log("The value of i is: " + i);
}
You can also use the for loop to iterate over elements of an array:
Example:
Example
const obj = { a: 1, b: 2, c: 3 };
for (let key in obj) {
console.log(key, obj[key]);
}
Output:
a1
b2
c3
● Used to iterate over iterable objects such as arrays, strings, maps, sets, etc.
● Iterates over the values of the iterable, not the properties.
● Does not include properties that are not part of the object's prototype chain.
● The syntax is for (variable of iterable).
Example:
Output:
1
2
3
The while loop executes a block of code as long as a specified condition is true.
Example:
let i = 0;
while (i < 5) {
console.log("The value of i is: " + i);
i++;
}
Output:
The do...while loop is similar to the while loop, but the condition is evaluated after executing
the block of code. This means the block of code will always execute at least once.
do {
// code block to be executed
} while (condition);
Example:
let i = 0;
do {
console.log("The value of i is: " + i);
i++;
} while (i < 5);
Output:
Objects in JavaScript are collections of key-value pairs where keys are strings (or symbols) and
values can be of any data type, including other objects, functions, and primitive types
Object literals provide a convenient syntax for creating objects in JavaScript. They allow you to
define an object and its properties directly within your code, without the need for a constructor
function. Object literals are enclosed within curly braces {} and consist of zero or more
comma-separated key-value pairs.
Example:
// Object Literal for creating objects
let car = {
name: "Maruti 800",
topSpeed: 89,
run: function() {
console.log("car is running");
}
};
// we have already seen constructors like these:
// new Date();
Output:
GeneralCar {
name: 'Nissan',
topSpeed: 180,
run: [Function (anonymous)],
analyze: [Function (anonymous)]
} GeneralCar {
name: 'Marutu Alto',
topSpeed: 80,
run: [Function (anonymous)],
analyze: [Function (anonymous)]
} GeneralCar {
name: 'Mercedes',
topSpeed: 200,
run: [Function (anonymous)],
analyze: [Function (anonymous)]
}
Car Name:Nissan
Nissan Is Running
This car is slower by 20 Km/H than Mercedes
// console.log(rakeshAccount, johnAccount);
// ============================
const accounts = [];
const accountForm = document.querySelector('#accountForm');
const customerName = document.querySelector('#customerName');
const balance = document.querySelector('#balance');
1.3.3 Classes
In JavaScript, classes are a relatively recent addition introduced in ECMAScript 2015 (ES6).
They provide a more familiar syntax for creating objects and dealing with inheritance in a
way that is similar to class-based languages like Java or C++.
1.3.4 Inheritance
Inheritance is a fundamental concept in object-oriented programming (OOP) where a new
class (derived or child class) is created by inheriting properties and behaviors from an
existing class (base or parent class)
class Animal {
constructor(name, color) {
this.name = name
this.color = color
}
run() {
console.log(this.name + " is running!")
}
shout() {
console.log(this.name + " is barking!")
}
}
ani.shout()
m.eatBanana()
m.hide()
// ani.hide() //This will throw an error
// Parent class
class Employee {
constructor(name, role) {
this.name = name;
this.role = role;
}
// Method to be overridden
introduce() {
console.log(`Hi, I'm ${this.name}, and I work as a ${this.role}.`);
}
}
// Method overriding
introduce() {
console.log(`Hi, I'm ${this.name}, and I manage the team.`);
}
}
// Method overriding
introduce() {
console.log(`Hi, I'm ${this.name}, and I develop software.`);
}
}
// Create instances
let employee = new Employee('John', 'Employee');
let manager = new Manager('Alice');
let developer = new Developer('Bob');
In JavaScript, constructors cannot be overridden in the same way as regular methods. When
you extend a class, you can provide a new constructor in the subclass, but if you do so, you
must call super() to invoke the constructor of the parent class. This is because JavaScript
does not support method overloading, and the constructor is no exception. The super() call
ensures that the initialization logic of the parent class is executed before any additional logic
in the subclass constructor.
// Parent class
class Employee {
constructor(name, role) {
this.name = name;
this.role = role;
}
introduce() {
console.log(`Hi, I'm ${this.name}, and I work as a ${this.role}.`);
}
}
introduce() {
console.log(`Hi, I'm ${this.name}, a Manager with a team size of ${this.teamSize}.`);
}
}
introduce() {
console.log(`Hi, I'm ${this.name}, a Developer specializing in
${this.programmingLanguage}.`);
}
}
// Create instances
let employee = new Employee('John', 'Employee');
let manager = new Manager('Alice', 10);
let developer = new Developer('Bob', 'JavaScript');
class Animal {
constructor(name) {
this.name = name;
}
introduce() {
console.log(`Hi, I'm ${this.name}.`);
}
}
introduce() {
console.log(`Hi, I'm ${this.name}, a ${this.breed} dog.`);
}
}
In this example:
● The Animal class has a constructor that initializes the name property.
● The Dog class extends Animal and has its constructor that initializes both the name
property (via super()) and the breed property.
● The introduce() method is overridden in both classes to provide different behaviors.
● When creating instances of Animal and Dog, the constructors of both classes are
invoked accordingly, with the subclass constructor replacing the superclass
constructor and optionally calling super() to ensure the superclass initialization logic
is executed.
1.3.7 Static Method
The JavaScript allows static methods that belong to the class rather than an instance of that
class. Hence, an instance is not needed to call such static methods. Static methods are
called on the class directly. It can be of any name. A class can contain more than one static
method. If we define more than one static method with the same name, the last method is
invoked by JavaScript. “this” keyword is used to call a static method within any other static
method in JavaScript.
Encapsulation is the bundling of data (attributes) and methods (functions) that operate on
the data into a single unit or class. This helps in hiding the internal state of an object and
only exposing necessary functionality to interact with it. Encapsulation helps in reducing
complexity, improving reusability, and preventing unintended modification of data.
Encapsulation ensures that the internal state of the object is protected and can only be
accessed or modified through controlled interfaces provided by getter and setter methods,
thus promoting data integrity and security.
1.4.2 Abstraction
Abstraction is the process of hiding the complex implementation details and showing only
the necessary features of an object or class. It allows developers to focus on what an object
does rather than how it does it. Abstraction helps in managing complexity, enhancing
maintainability, and facilitating code reuse.
1.4.3 Inheritance
Inheritance is the mechanism by which a class can inherit properties and methods from
another class (superclass or base class). It promotes code reuse by allowing subclasses to
reuse and extend the functionality of their parent classes. Inheritance enables hierarchical
classification and organization of classes, making the code more scalable and modular.
1.4.4 Polymorphism
// Parent class
class Animal {
constructor(name) {
this.name = name;
}
// Child class 1
class Dog extends Animal {
// Method overriding
makeSound() {
console.log(`${this.name} barks.`);
}
}
// Child class 2
class Cat extends Animal {
// Method overriding
makeSound() {
console.log(`${this.name} meows.`);
}
}
In this example, we have a parent class Animal with a method makeSound(). The Dog and
Cat classes extend the Animal class and override the makeSound() method with their own
implementations. The animalSound() function demonstrates polymorphism by accepting any
object that inherits from the Animal class and calling its makeSound() method. Depending on
the type of object passed, it invokes the appropriate overridden method, exhibiting
polymorphic behavior.
1.5 TypeScript
We said earlier that some languages wouldn’t allow those buggy programs to run at all.
Detecting errors in code without running it is referred to as static checking. Determining
what’s an error and what’s not based on the kinds of values being operated on is known as
static type checking.
TypeScript checks a program for errors before execution, and does so based on the kinds of
values, making it a static type checker. For example, the last example above has an error
because of the type of obj. Here’s the error TypeScript found:
Property 'heigth' does not exist on type '{ width: number; height: number; }'. Did you mean
'height'?
Built-in Data
keyword Description
Type
Null null It is used when an object does not have any value
1.5.3 Interfaces
In TypeScript, interfaces are a powerful way to define the shape or structure of an object.
They are like a contract that specifies which properties and methods an object must have.
This allows you to enforce a certain structure across your codebase, making it more
predictable and maintainable.
Example:
interface Person {
name: string;
age: number;
}
Properties of Interfaces
1. Extending properties:
TypeScript allows interfaces to extend existing interfaces. This enables us to add new
properties to an interface while reusing properties from another.
Example:
interface For_Array {
var1: string;
}
interface For_List extends For_Array {
var2: string;
}
Here for list interface contain var2 property and extend the var1 property of For_Array
property.
2. Optional Properties
You can also define properties that may or may not be present in the implementing object.
These properties are marked with a ? symbol.
Example:
interface Car {
brand: string;
model?: string; // Optional property
}
In this example, the Car interface has a required brand property and an optional model
property marked with ?. The displayCar function takes a Car object as an argument and
displays its brand and model if the model is provided. When calling displayCar, you can pass
objects with or without the model property.
Example:
interface ForFunc {
(key: string, value?: string): void;
}
Explanation:
interface ForFunc {
(key: string, value?: string): void;
}
newFunc("Interface", "Function");
● newFunc is called with two arguments: "Interface" for key and "Function" for value.
● Since value is optional in the ForFunc interface, it's valid to call newFunc with just
one argument (key)
1.5.4 Classes
In TypeScript, an enum, short for "enumeration," is a data type that allows you to define a set
of named constants. Enums are useful when you have a fixed set of values that a variable
can take. They make your code more readable and maintainable by providing meaningful
names to these values.
Place to use an enum: Enums should be used whenever there is a small set of fixed values
available that are closely related and further these values are known at compile time.
1.5.6 Generics
Generics in TypeScript allow you to create reusable components and functions that can work
with a variety of data types while still maintaining type safety. Generics enable you to define
functions, classes, and interfaces with placeholders for types, which are filled in when the
component is used.
Generic Functions:
Generics in functions allow you to define placeholders for the types of parameters and return
values. This makes functions more flexible and reusable across different data types.
Syntax:
function functionName<T> (returnValue : T) : T {
return returnValue;
}
Example 1: In this example, we have created a generic function that can accept any type of
data, we need to pass the value in the parameter by giving them any kind of data type and
then we can reverse that value by the use of the reverseArray function.
console.log(strArray);
console.log(numArray);
console.log(boolArray);
Generic Interfaces:
Interfaces can also be generic, allowing you to define placeholders for types in interface
declarations.
Example 2: In this example, we have created a generic interface by using that we are
creating object and string type of value and printing them in the console.
interface Resource<T> {
id: number;
resourceName: string;
data: T;
}
const person: Resource<object> = {
// Generic interface with objects
id: 1,
resourceName: 'Person',
data: {
name: 'John',
age: 25,
}
}
console.log(person);
const employee: Resource<string[]> =
{
// Generic interface with strings array
id: 2,
resourceName: 'Employee',
data: ['Employee 1', 'Employee 1']
}
console.log(employee);
Generic Classes:
Generics in classes enable you to create classes with members whose types are specified
by the user when the class is instantiated.
class Queue<T> {
private elements: T[] = [];
dequeue(): T | undefined {
return this.elements.shift();
}
isEmpty(): boolean {
return this.elements.length === 0;
}
peek(): T | undefined {
return this.elements[0];
}
size(): number {
return this.elements.length;
}
}
// Example usage:
const stringQueue = new Queue<string>();
stringQueue.enqueue("first");
stringQueue.enqueue("second");
stringQueue.enqueue("third");
TypeScript constraints are used in generic type declarations to restrict the types that can be
used as type arguments for the generic. Constraints allow you to specify that a generic type
parameter must meet certain criteria, such as implementing a particular interface, having a
specific method, or extending a specific class. This ensures type safety and enhances code
predictability.
Syntax:
function functionName<T extends ConstraintType>(param: T): ReturnType {
// Function implementation
}
Parameters:
● T is the generic type parameter.
● extends is used to specify the constraint.
● ConstraintType is the type or interface that T must extend or implement.
● param is the parameter that must be of type T.
● ReturnType is the return type of the function.
Example 1:
function whatIsLength<Type extends { length: number }>
(x: Type, y: Type) {
if (x.length >= y.length) {
return ("x is larger than y");
} else {
return ("x is smaller than y");;
}
}
SELECT*FROM employee; --to retrieve data from a database, we use select statment.
--to remove a column we have to use first alter table and then drop keyword.
ALTER TABLE employee
DROP yearsofservice;
SELECT*FROM employee;
-- to change data type or the size of a table column we have to use alter table / alter column
-- we want to change the data type of workmode into just 0 or 1, so its data type should be
integer
-- ALTER TABLE employee
-- ALTER COLUMN workmode type integer;
/* Delete Statement
Be careful when deleting records in a table! Notice the WHERE clause in the DELETE
statement.
The WHERE clause specifies which record(s) should be deleted.
If you omit the WHERE clause,
all records in the table will be deleted!.*/
example */
delete from employee; -- delete all record in the employee table
SELECT*FROM employee;
-- TRUNCATE TABLE
/* because we omit the where clause in the delete statement above, all records will be
deleted from the employee table.
the same would have been achieved by using the TRUNCATE TABLE statement*/
-- DROP TABLE
DROP TABLE employee;
-- SELECT * FROM employee; it will give an error that employee does not exist