Welcome to the "Fundamentals of Programming" repository! 🚀
Welcome to the "Fundamentals of Programming" open-source repository! 🚀 This repository serves as a comprehensive resource for individuals seeking to understand and master the fundamental concepts of programming.
#Programming #CodeLearning #GitHub #CodingBeginner #TechEd #CodePractice
Programming languages make use of the computer's memory to 'remember' previous information to be used throughout a program's execution, such as specific values, names and inputs. These are stored in allocations of the computer's memory called variables.
In JavaScript, variables are used to store data values. You can declare variables using three keywords: var
, let
, and const
. Each of these keywords has different scopes and properties. Let's explore these in detail:
-
var
- Function-scoped or globally scoped if declared outside a function.
- Can be redeclared and updated.
- Hoisted to the top of their scope, initialized with
undefined
.
var x = 10; console.log(x); // 10
-
let
- Block-scoped, meaning the variable is only accessible within the block where it's declared.
- Can be updated but not redeclared within the same scope.
- Hoisted to the top of their block, but not initialized, so accessing them before the declaration results in a ReferenceError.
let y = 20; y = 25; console.log(y); // 25
-
const
- Block-scoped like
let
. - Must be initialized at the time of declaration and cannot be updated or redeclared.
- Hoisted to the top of their block, but not initialized, so accessing them before the declaration results in a ReferenceError.
const z = 30; // z = 35; // Error: Assignment to constant variable. console.log(z); // 30
- Block-scoped like
-
Global Scope
- Variables declared outside of any function or block have global scope.
- Accessible from anywhere in the code.
var globalVar = "I am global"; function testGlobalScope() { console.log(globalVar); // I am global }
-
Function Scope
- Variables declared inside a function using
var
are scoped to that function.
function testFunctionScope() { var localVar = "I am local"; console.log(localVar); // I am local } // console.log(localVar); // Error: localVar is not defined
- Variables declared inside a function using
-
Block Scope
- Variables declared with
let
orconst
inside a block{}
are scoped to that block.
if (true) { let blockVar = "I am block-scoped"; const anotherBlockVar = "I am also block-scoped"; console.log(blockVar); // I am block-scoped console.log(anotherBlockVar); // I am also block-scoped } // console.log(blockVar); // Error: blockVar is not defined // console.log(anotherBlockVar); // Error: anotherBlockVar is not defined
- Variables declared with
-
var
- Hoisted to the top of their function scope and initialized with
undefined
.
console.log(a); // undefined var a = 10;
- Hoisted to the top of their function scope and initialized with
-
let and const
- Hoisted to the top of their block scope but not initialized, resulting in a ReferenceError if accessed before declaration.
// console.log(b); // Error: Cannot access 'b' before initialization let b = 20;
-
var
- Can be reassigned and redeclared within its scope.
var c = 1; var c = 2; // No error c = 3; console.log(c); // 3
-
let
- Can be reassigned but not redeclared within its block scope.
let d = 4; // let d = 5; // Error: Identifier 'd' has already been declared d = 6; console.log(d); // 6
-
const
- Cannot be reassigned or redeclared.
const e = 7; // e = 8; // Error: Assignment to constant variable. // const e = 9; // Error: Identifier 'e' has already been declared console.log(e); // 7
Understanding these concepts is essential for effective and predictable JavaScript programming. The choice of var
, let
, or const
depends on the specific needs for scope, mutability, and redeclaration.
In JavaScript, there are several data types that can be categorized into two main groups: primitive and non-primitive (or reference) data types. Here’s an overview:
-
Number:
- Represents both integer and floating-point numbers.
- Example:
42
,3.14
-
String:
- Represents a sequence of characters.
- Example:
"hello"
,'world'
-
Boolean:
- Represents a logical entity with two values:
true
andfalse
. - Example:
true
,false
- Represents a logical entity with two values:
-
Undefined:
- Represents a variable that has been declared but not assigned a value.
- Example:
let x; // x is undefined
-
Null:
- Represents the intentional absence of any object value.
- Example:
let y = null;
-
Symbol:
- Represents a unique and immutable value that can be used as the key of an object property.
- Example:
let sym = Symbol('description');
-
BigInt:
- Represents whole numbers larger than
2^53 - 1
(which is the largest number JavaScript can reliably represent with the Number primitive). - Example:
let bigInt = 1234567890123456789012345678901234567890n;
- Represents whole numbers larger than
-
Object:
- Represents a collection of properties and methods.
- Example:
let obj = { name: "John", age: 30 };
-
Array:
- A special type of object used to store multiple values in a single variable.
- Example:
let arr = [1, 2, 3, 4, 5];
-
Function:
- Another special type of object that can be invoked.
- Example:
function greet() { return "Hello, World!"; }
-
Date:
- Represents a single moment in time.
- Example:
let now = new Date();
-
Number:
let age = 25; let price = 19.99;
-
String:
let greeting = "Hello, World!"; let name = "Alice";
-
Boolean:
let isActive = true; let hasPermission = false;
-
Undefined:
let score; console.log(score); // undefined
-
Null:
let response = null;
-
Symbol:
let sym1 = Symbol(); let sym2 = Symbol("key");
-
BigInt:
let bigNumber = 9007199254740991n;
-
Object:
let person = { firstName: "John", lastName: "Doe", age: 30, };
-
Array:
let colors = ["red", "green", "blue"];
-
Function:
function add(a, b) { return a + b; }
-
Date:
let today = new Date();
Understanding these data types and their properties is fundamental to working with JavaScript effectively. Each type has its own unique characteristics and uses within the language.
JavaScript provides a rich set of operators for performing various operations on values. These operators can be categorized into several types:
Arithmetic operators are used to perform mathematical operations.
-
Addition (
+
): Adds two operands.let sum = 10 + 5; // 15
-
Subtraction (
-
): Subtracts the second operand from the first.let difference = 10 - 5; // 5
-
Multiplication (
*
): Multiplies two operands.let product = 10 * 5; // 50
-
Division (
/
): Divides the first operand by the second.let quotient = 10 / 5; // 2
-
Modulus (
%
): Returns the remainder of a division.let remainder = 10 % 3; // 1
-
**Exponentiation (
**
)**: Raises the first operand to the power of the second.let power = 2 ** 3; // 8
-
Increment (
++
): Increases an operand by 1.let x = 5; x++; // 6
-
Decrement (
--
): Decreases an operand by 1.let y = 5; y--; // 4
Assignment operators are used to assign values to variables.
-
Assignment (
=
): Assigns the right operand's value to the left operand.let a = 10;
-
Addition assignment (
+=
): Adds the right operand to the left operand and assigns the result to the left operand.a += 5; // a = a + 5
-
Subtraction assignment (
-=
): Subtracts the right operand from the left operand and assigns the result to the left operand.a -= 3; // a = a - 3
-
Multiplication assignment (
*=
): Multiplies the left operand by the right operand and assigns the result to the left operand.a *= 2; // a = a * 2
-
Division assignment (
/=
): Divides the left operand by the right operand and assigns the result to the left operand.a /= 2; // a = a / 2
-
Modulus assignment (
%=
): Performs modulus operation on the left operand with the right operand and assigns the result to the left operand.a %= 3; // a = a % 3
-
**Exponentiation assignment (
**=
)**: Raises the left operand to the power of the right operand and assigns the result to the left operand.a **= 2; // a = a ** 2
Comparison operators are used to compare two values.
-
Equal (
==
): Checks if two values are equal (abstract equality).5 == "5"; // true
-
Not equal (
!=
): Checks if two values are not equal.5 != "5"; // false
-
Strict equal (
===
): Checks if two values are equal (strict equality).5 === 5; // true 5 === "5"; // false
-
Strict not equal (
!==
): Checks if two values are not equal (strict inequality).5 !== "5"; // true
-
Greater than (
>
): Checks if the left operand is greater than the right.10 > 5; // true
-
Greater than or equal (
>=
): Checks if the left operand is greater than or equal to the right.10 >= 10; // true
-
Less than (
<
): Checks if the left operand is less than the right.5 < 10; // true
-
Less than or equal (
<=
): Checks if the left operand is less than or equal to the right.5 <= 5; // true
Logical operators are used to combine multiple Boolean expressions or values.
-
Logical AND (
&&
): Returns true if both operands are true.true && false; // false
-
Logical OR (
||
): Returns true if at least one of the operands is true.true || false; // true
-
Logical NOT (
!
): Returns true if the operand is false, and vice versa.!true; // false
Bitwise operators are used to perform operations on binary representations of numbers.
-
AND (
&
): Performs a bitwise AND.5 & 1; // 1
-
OR (
|
): Performs a bitwise OR.5 | 1; // 5
-
XOR (
^
): Performs a bitwise XOR.5 ^ 1; // 4
-
NOT (
~
): Performs a bitwise NOT.~5; // -6
-
Left shift (
<<
): Shifts bits to the left.5 << 1; // 10
-
Right shift (
>>
): Shifts bits to the right.5 >> 1; // 2
-
Zero-fill right shift (
>>>
): Shifts bits to the right, filling the left with zeros.5 >>> 1; // 2
String operators are used to concatenate strings.
-
Concatenation (
+
): Joins two or more strings.let greeting = "Hello, " + "world!"; // "Hello, world!"
-
Concatenation assignment (
+=
): Adds the right operand to the end of the left operand.let message = "Hello"; message += ", world!"; // "Hello, world!"
The ternary operator is a shorthand for the if...else
statement.
- Ternary (
? :
): Evaluates a condition and returns one value if true and another if false.let isAdult = age >= 18 ? "Yes" : "No";
Type operators are used to determine the type of a variable.
-
typeof: Returns the type of a variable.
typeof 42; // "number" typeof "hello"; // "string"
-
instanceof: Checks if an object is an instance of a specific class or constructor.
let date = new Date(); date instanceof Date; // true
Understanding and using these operators effectively is crucial for writing efficient and readable JavaScript code.
Control structures in JavaScript are constructs that control the flow of execution in a program. They allow you to make decisions, repeat actions, and manage the sequence of operations. Here's an overview of the primary control structures in JavaScript:
Executes a block of code if a specified condition is true.
if (condition) {
// code to be executed if condition is true
}
Example:
let age = 18;
if (age >= 18) {
console.log("You are an adult.");
}
Executes one block of code if a condition is true, and another block if it is false.
if (condition) {
// code to be executed if condition is true
} else {
// code to be executed if condition is false
}
Example:
let age = 16;
if (age >= 18) {
console.log("You are an adult.");
} else {
console.log("You are not an adult.");
}
Executes different blocks of code depending on multiple conditions.
if (condition1) {
// code to be executed if condition1 is true
} else if (condition2) {
// code to be executed if condition2 is true
} else {
// code to be executed if neither condition1 nor condition2 is true
}
Example:
let score = 85;
if (score >= 90) {
console.log("Grade A");
} else if (score >= 80) {
console.log("Grade B");
} else {
console.log("Grade C");
}
Evaluates an expression and executes the corresponding case block.
switch (expression) {
case value1:
// code to be executed if expression === value1
break;
case value2:
// code to be executed if expression === value2
break;
default:
// code to be executed if expression doesn't match any case
}
Example:
let day = 3;
switch (day) {
case 1:
console.log("Monday");
break;
case 2:
console.log("Tuesday");
break;
case 3:
console.log("Wednesday");
break;
default:
console.log("Another day");
}
Repeats a block of code a specified number of times.
for (initialization; condition; increment) {
// code to be executed
}
Example:
for (let i = 0; i < 5; i++) {
console.log(i);
}
Repeats a block of code as long as a specified condition is true.
while (condition) {
// code to be executed
}
Example:
let i = 0;
while (i < 5) {
console.log(i);
i++;
}
Repeats a block of code at least once, and then continues as long as a specified condition is true.
do {
// code to be executed
} while (condition);
Example:
let i = 0;
do {
console.log(i);
i++;
} while (i < 5);
Iterates over the properties of an object.
for (key in object) {
// code to be executed
}
Example:
let person = { name: "John", age: 30, city: "New York" };
for (let key in person) {
console.log(key + ": " + person[key]);
}
Iterates over iterable objects like arrays, strings, maps, sets, etc.
for (variable of iterable) {
// code to be executed
}
Example:
let arr = [1, 2, 3, 4, 5];
for (let value of arr) {
console.log(value);
}
Terminates the current loop, switch, or label statement and transfers program control to the statement following the terminated statement.
for (let i = 0; i < 10; i++) {
if (i === 5) {
break;
}
console.log(i);
}
Skips the rest of the code in the current iteration of the loop and moves to the next iteration.
for (let i = 0; i < 10; i++) {
if (i === 5) {
continue;
}
console.log(i);
}
Marks a block of statements to try and specifies a response should an exception be thrown.
try {
// code to try
} catch (error) {
// code to handle errors
} finally {
// code to execute regardless of the try / catch result
}
Example:
try {
let result = riskyFunction();
console.log(result);
} catch (error) {
console.error("An error occurred:", error);
} finally {
console.log("Execution completed.");
}
Throws a user-defined exception.
if (condition) {
throw new Error("Something went wrong");
}
Example:
function checkAge(age) {
if (age < 18) {
throw new Error("You must be at least 18 years old.");
}
return "Access granted.";
}
try {
let result = checkAge(15);
console.log(result);
} catch (error) {
console.error(error.message);
}
These control structures allow you to manage the flow of your JavaScript programs effectively, making it possible to implement complex logic and handle different scenarios and conditions.
- Function: A self-contained block of code that performs a specific task. It can be called and executed from other parts of the program.
- Method: A function that is associated with an object or a class in object-oriented programming.
Functions and methods are fundamental concepts in JavaScript that allow you to encapsulate code into reusable blocks. Understanding the difference between functions and methods, as well as how to define and use them, is crucial for effective JavaScript programming.
A function is a block of code designed to perform a particular task. It is executed when "called" (invoked).
- Function Declaration
function functionName(parameters) {
// code to be executed
}
Example:
function greet(name) {
return `Hello, ${name}!`;
}
console.log(greet("Alice")); // Hello, Alice!
- Function Expression
A function can also be defined using an expression. A function expression can be anonymous or named.
const functionName = function (parameters) {
// code to be executed
};
Example:
const greet = function (name) {
return `Hello, ${name}!`;
};
console.log(greet("Bob")); // Hello, Bob!
- Arrow Function Expression
Arrow functions provide a shorter syntax and are always anonymous.
const functionName = (parameters) => {
// code to be executed
};
Example:
const greet = (name) => `Hello, ${name}!`;
console.log(greet("Charlie")); // Hello, Charlie!
You invoke a function by calling its name followed by parentheses, optionally passing arguments.
functionName(arguments);
Example:
greet("Dave"); // Invokes the greet function with "Dave" as an argument
A method is a function that is a property of an object. Methods are defined the same way as normal functions but are invoked on objects.
- Within an Object Literal
const obj = {
methodName: function (parameters) {
// code to be executed
},
};
Example:
const person = {
name: "Alice",
greet: function () {
return `Hello, my name is ${this.name}`;
},
};
console.log(person.greet()); // Hello, my name is Alice
- Using ES6 Shorthand Syntax
const obj = {
methodName(parameters) {
// code to be executed
},
};
Example:
const person = {
name: "Bob",
greet() {
return `Hello, my name is ${this.name}`;
},
};
console.log(person.greet()); // Hello, my name is Bob
Functions have their own scope in JavaScript. Variables defined inside a function are not accessible outside of it. A closure is a function that retains access to its lexical scope even when the function is executed outside that scope.
Example of Closure:
function outerFunction(outerVariable) {
return function innerFunction(innerVariable) {
return `Outer: ${outerVariable}, Inner: ${innerVariable}`;
};
}
const newFunction = outerFunction("outside");
console.log(newFunction("inside")); // Outer: outside, Inner: inside
A higher-order function is a function that can take other functions as arguments or return them.
Example:
function multiplyBy(factor) {
return function (number) {
return number * factor;
};
}
const double = multiplyBy(2);
console.log(double(5)); // 10
An IIFE is a function that is executed immediately after it is defined.
Example:
(function () {
console.log("This is an IIFE!");
})();
A recursive function is a function that calls itself.
Example:
function factorial(n) {
if (n === 0) {
return 1;
}
return n * factorial(n - 1);
}
console.log(factorial(5)); // 120
-
Default Parameters: Provide default values for function parameters.
function greet(name = "Guest") { return `Hello, ${name}!`; } console.log(greet()); // Hello, Guest!
-
Rest Parameters: Collect all remaining arguments into an array.
function sum(...numbers) { return numbers.reduce((total, num) => total + num, 0); } console.log(sum(1, 2, 3, 4)); // 10
In JavaScript, the value of this
inside a method depends on how the method is called. Methods can be explicitly bound to objects using bind
, call
, or apply
.
Example:
const person = {
name: "Charlie",
greet() {
return `Hello, my name is ${this.name}`;
},
};
const greet = person.greet;
console.log(greet()); // Undefined, because 'this' is not bound
const boundGreet = person.greet.bind(person);
console.log(boundGreet()); // Hello, my name is Charlie
Understanding and effectively utilizing functions and methods are essential for writing modular, reusable, and maintainable JavaScript code.
- The order in which statements and instructions are executed in a program. It is determined by the control structures and loops.
-
Arrays and Collections:
- Array: A data structure that stores a collection of elements, each identified by an index or a key.
- Collections: More advanced data structures, like lists, sets, and maps, that can hold multiple elements.
In JavaScript, arrays and collections are used to store and manage groups of data. They provide various methods and properties to facilitate data manipulation and access. Here's a detailed look at arrays and collections in JavaScript:
An array is a special type of object used for storing multiple values in a single variable. Arrays are zero-indexed, meaning the first element has an index of 0.
- Using Array Literals
let fruits = ["Apple", "Banana", "Cherry"];
- Using the Array Constructor
let fruits = new Array("Apple", "Banana", "Cherry");
- Creating an Empty Array
let emptyArray = [];
You can access and modify array elements using their index.
let fruits = ["Apple", "Banana", "Cherry"];
console.log(fruits[0]); // Access first element: Apple
fruits[1] = "Blueberry"; // Modify second element
console.log(fruits[1]); // Blueberry
-
length Returns the number of elements in the array.
let fruits = ["Apple", "Banana", "Cherry"]; console.log(fruits.length); // 3
-
push() Adds one or more elements to the end of an array and returns the new length.
let fruits = ["Apple", "Banana"]; fruits.push("Cherry"); console.log(fruits); // ["Apple", "Banana", "Cherry"]
-
pop() Removes the last element from an array and returns that element.
let fruits = ["Apple", "Banana", "Cherry"]; let lastFruit = fruits.pop(); console.log(lastFruit); // Cherry console.log(fruits); // ["Apple", "Banana"]
-
shift() Removes the first element from an array and returns that element.
let fruits = ["Apple", "Banana", "Cherry"]; let firstFruit = fruits.shift(); console.log(firstFruit); // Apple console.log(fruits); // ["Banana", "Cherry"]
-
unshift() Adds one or more elements to the beginning of an array and returns the new length.
let fruits = ["Banana", "Cherry"]; fruits.unshift("Apple"); console.log(fruits); // ["Apple", "Banana", "Cherry"]
-
splice() Adds or removes elements from an array.
let fruits = ["Apple", "Banana", "Cherry"]; fruits.splice(1, 1, "Blueberry"); console.log(fruits); // ["Apple", "Blueberry", "Cherry"]
-
slice() Returns a shallow copy of a portion of an array into a new array.
let fruits = ["Apple", "Banana", "Cherry"]; let newFruits = fruits.slice(1, 3); console.log(newFruits); // ["Banana", "Cherry"]
-
concat() Merges two or more arrays into one.
let fruits = ["Apple", "Banana"]; let moreFruits = ["Cherry", "Date"]; let allFruits = fruits.concat(moreFruits); console.log(allFruits); // ["Apple", "Banana", "Cherry", "Date"]
-
forEach() Executes a provided function once for each array element.
let fruits = ["Apple", "Banana", "Cherry"]; fruits.forEach(function (fruit) { console.log(fruit); });
-
map() Creates a new array with the results of calling a provided function on every element.
let numbers = [1, 2, 3]; let squares = numbers.map(function (num) { return num * num; }); console.log(squares); // [1, 4, 9]
-
filter() Creates a new array with all elements that pass the test implemented by the provided function.
let numbers = [1, 2, 3, 4, 5]; let evenNumbers = numbers.filter(function (num) { return num % 2 === 0; }); console.log(evenNumbers); // [2, 4]
-
reduce() Executes a reducer function on each element of the array, resulting in a single output value.
let numbers = [1, 2, 3, 4, 5]; let sum = numbers.reduce(function (total, num) { return total + num; }, 0); console.log(sum); // 15
-
find() Returns the first element in the array that satisfies the provided testing function.
let numbers = [1, 2, 3, 4, 5]; let firstEven = numbers.find(function (num) { return num % 2 === 0; }); console.log(firstEven); // 2
-
includes() Determines whether an array includes a certain value.
let fruits = ["Apple", "Banana", "Cherry"]; console.log(fruits.includes("Banana")); // true
JavaScript also provides built-in objects like Set
and Map
for collections, which offer more flexible and efficient ways to manage data.
A Set
is a collection of unique values.
-
Creating a Set
let mySet = new Set();
-
Adding Values
mySet.add(1); mySet.add(5); mySet.add(1); // Duplicate values are ignored console.log(mySet); // Set { 1, 5 }
-
Checking for Values
console.log(mySet.has(1)); // true console.log(mySet.has(3)); // false
-
Removing Values
mySet.delete(5); console.log(mySet); // Set { 1 }
-
Iterating Over a Set
mySet.add(2).add(3); for (let value of mySet) { console.log(value); }
A Map
is a collection of key-value pairs.
-
Creating a Map
let myMap = new Map();
-
Setting Key-Value Pairs
myMap.set("name", "John"); myMap.set("age", 30);
-
Getting Values
console.log(myMap.get("name")); // John console.log(myMap.get("age")); // 30
-
Checking for Keys
console.log(myMap.has("name")); // true console.log(myMap.has("address")); // false
-
Deleting Key-Value Pairs
myMap.delete("age"); console.log(myMap); // Map { "name" => "John" }
-
Iterating Over a Map
myMap.set("gender", "male"); for (let [key, value] of myMap) { console.log(`${key}: ${value}`); }
Typed arrays are used for handling binary data. They allow you to create arrays of specific types of data, such as Int8Array
, Uint8Array
, Float32Array
, etc.
Example:
let buffer = new ArrayBuffer(16); // Create a buffer of 16 bytes
let int32View = new Int32Array(buffer);
int32View[0] = 42;
console.log(int32View[0]); // 42
- Arrays: Used for storing multiple values in a single variable. They offer various methods and properties for manipulation and access.
- Sets: Collections of unique values, ensuring no duplicates.
- Maps: Collections of key-value pairs, allowing for fast retrieval and manipulation of data.
- Typed Arrays: Used for handling binary data efficiently.
Understanding and utilizing these data structures effectively allows you to manage and manipulate data in your JavaScript applications efficiently.
- Mechanisms for receiving input from users (keyboard, mouse, etc.) and producing output (displaying information, writing to files, etc.). In JavaScript, input and output (I/O) operations allow programs to interact with the user and other systems. These operations are essential for creating interactive web applications. Here's an overview of various I/O mechanisms in JavaScript:
Prompt
The prompt
function displays a dialog box that prompts the user for input.
let userInput = prompt("Please enter your name:");
console.log(userInput); // Output the user's input to the console
Forms HTML forms are commonly used for input in web applications. JavaScript can handle form data through event listeners.
HTML:
<form id="myForm">
<label for="name">Name:</label>
<input type="text" id="name" name="name" />
<input type="submit" value="Submit" />
</form>
JavaScript:
document.getElementById("myForm").addEventListener("submit", function (event) {
event.preventDefault(); // Prevent the form from submitting the traditional way
let name = document.getElementById("name").value;
console.log(name); // Output the form data to the console
});
Event Listeners Event listeners can be used to capture various user interactions, such as clicks, key presses, and mouse movements.
document.getElementById("myButton").addEventListener("click", function () {
console.log("Button clicked!");
});
Reading from the Command Line
In Node.js, you can read input from the command line using the readline
module.
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
rl.question("What is your name? ", function (name) {
console.log(`Hello, ${name}!`);
rl.close();
});
Console
The console
object provides methods for logging output to the browser's console.
console.log("Hello, world!");
console.error("An error occurred!");
console.warn("This is a warning!");
console.info("This is some information.");
Alerts
The alert
function displays an alert dialog with a specified message.
alert("This is an alert!");
DOM Manipulation You can dynamically update the HTML content using JavaScript.
HTML:
<p id="output">Original text</p>
<button id="updateButton">Update Text</button>
JavaScript:
document.getElementById("updateButton").addEventListener("click", function () {
document.getElementById("output").innerText = "Text has been updated!";
});
Writing to the Document
You can write directly to the document using document.write
, but this is generally not recommended for modern applications.
document.write("This is written to the document.");
Console
Similar to browser-based JavaScript, Node.js also provides the console
object for logging output.
console.log("Hello, Node.js!");
console.error("An error occurred in Node.js!");
console.warn("This is a warning in Node.js!");
console.info("This is some information in Node.js.");
Writing to Files
Node.js allows writing to files using the fs
module.
const fs = require("fs");
fs.writeFile("output.txt", "Hello, file system!", function (err) {
if (err) {
console.error("An error occurred while writing to the file!");
} else {
console.log("File has been written successfully!");
}
});
Here’s a simple example that combines input and output in a web application:
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Interactive Page</title>
</head>
<body>
<h1>Interactive Page</h1>
<label for="userName">Enter your name:</label>
<input type="text" id="userName" />
<button id="greetButton">Greet</button>
<p id="greeting"></p>
<script src="script.js"></script>
</body>
</html>
JavaScript (script.js
):
document.getElementById("greetButton").addEventListener("click", function () {
let userName = document.getElementById("userName").value;
let greetingMessage = `Hello, ${userName}! Welcome to the interactive page.`;
document.getElementById("greeting").innerText = greetingMessage;
});
- Input in JavaScript can be obtained from prompts, forms, event listeners, or command line inputs (Node.js).
- Output can be displayed using the console, alerts, DOM manipulation, or by writing to files (Node.js).
- Combining these input and output methods allows for creating interactive and dynamic web applications.
- Breaking down a program into smaller, manageable parts (modules or functions) to enhance readability, maintainability, and encourage code reuse.
Modularity and code reusability are key principles in software development that help create maintainable, scalable, and efficient applications. In JavaScript, these principles are implemented using functions, modules, and other techniques that promote separation of concerns and reusability.
Functions are the basic building blocks for modularity and code reusability in JavaScript. They allow you to encapsulate code into reusable pieces.
Example:
function add(a, b) {
return a + b;
}
let sum = add(2, 3);
console.log(sum); // 5
JavaScript modules allow you to break up your code into separate files, each containing related code. This improves the maintainability and reusability of your code.
ES6 introduced native support for modules using import
and export
statements.
Example:
math.js:
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
main.js:
import { add, subtract } from "./math.js";
console.log(add(2, 3)); // 5
console.log(subtract(5, 2)); // 3
CommonJS is used primarily in Node.js. Modules are defined using module.exports
and require
.
Example:
math.js:
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
module.exports = {
add,
subtract,
};
main.js:
const math = require("./math.js");
console.log(math.add(2, 3)); // 5
console.log(math.subtract(5, 2)); // 3
Higher-order functions are functions that operate on other functions, either by taking them as arguments or by returning them. This can greatly enhance code reusability.
Example:
function greet(name) {
return function (message) {
console.log(`${message}, ${name}!`);
};
}
let greetJohn = greet("John");
greetJohn("Hello"); // Hello, John!
greetJohn("Goodbye"); // Goodbye, John!
Using design patterns such as the module pattern, factory pattern, and singleton pattern can also enhance modularity and code reusability.
Module Pattern:
const myModule = (function () {
let privateVar = "I am private";
function privateFunction() {
console.log(privateVar);
}
return {
publicMethod: function () {
privateFunction();
},
};
})();
myModule.publicMethod(); // I am private
Leveraging libraries and frameworks can promote code reusability by allowing you to use pre-built, tested, and optimized code.
Example:
Using Lodash, a utility library:
import _ from "lodash";
let array = [1, 2, 3, 4];
let doubled = _.map(array, (num) => num * 2);
console.log(doubled); // [2, 4, 6, 8]
Proper code organization and project structure also play a crucial role in modularity and reusability.
Example:
Project Structure:
/project
/src
/components
Header.js
Footer.js
/utils
math.js
App.js
index.html
- Functions: Encapsulate code into reusable pieces.
- Modules: Break up code into separate files for maintainability and reusability.
- Higher-Order Functions: Functions that operate on other functions.
- Design Patterns: Utilize patterns like module pattern, factory pattern, etc., to enhance modularity.
- Libraries and Frameworks: Leverage pre-built code to avoid reinventing the wheel.
- Code Organization: Maintain a clear and structured project layout to promote reusability and maintainability.
By adhering to these principles and techniques, you can write more modular, reusable, and maintainable JavaScript code.
Techniques and mechanisms for detecting and managing errors or exceptions in a program to prevent unexpected behavior.
Error handling in JavaScript is crucial for writing robust and reliable applications. JavaScript provides various mechanisms for handling errors and exceptions that may occur during the execution of code. Here's an overview of error handling in JavaScript:
The try...catch
statement is used to handle exceptions (errors) that occur within a block of code.
try {
// Code that may throw an error
throw new Error("Something went wrong!");
} catch (error) {
// Code to handle the error
console.error(error);
}
The throw
statement is used to throw a custom error. This can be an instance of the Error
object or any other type of object.
function divide(a, b) {
if (b === 0) {
throw new Error("Division by zero is not allowed.");
}
return a / b;
}
try {
let result = divide(10, 0);
console.log(result);
} catch (error) {
console.error(error);
}
JavaScript provides the Error
object, which represents an error. It has properties like name
and message
that provide information about the error.
try {
throw new Error("Custom error message");
} catch (error) {
console.error(error.name); // "Error"
console.error(error.message); // "Custom error message"
}
JavaScript provides various built-in error types that extend the Error
object, such as SyntaxError
, TypeError
, ReferenceError
, etc. You can catch specific types of errors using separate catch
blocks.
try {
// Code that may throw a TypeError
let x;
x.toUpperCase(); // Trying to access a property of undefined
} catch (error) {
if (error instanceof TypeError) {
console.error("TypeError:", error.message);
} else {
console.error("An error occurred:", error.message);
}
}
The finally
block is used to execute code, regardless of whether an error occurred or not. It's often used for cleanup tasks.
try {
// Code that may throw an error
} catch (error) {
// Code to handle the error
} finally {
// Code to execute regardless of whether an error occurred
}
You can use the window.onerror
event handler or the uncaughtException
event in Node.js to catch unhandled errors globally.
window.onerror = function (message, source, lineno, colno, error) {
console.error("An error occurred:", message, source, lineno, colno, error);
};
Handling errors in asynchronous code (e.g., promises, callbacks) requires a different approach. With promises, you can use the .catch()
method to handle errors. With async/await, you can use try...catch
blocks as usual.
async function fetchData() {
try {
let response = await fetch("https://api.example.com/data");
let data = await response.json();
console.log(data);
} catch (error) {
console.error("Error fetching data:", error);
}
}
You can define custom error types by extending the Error
object to provide more specific information about errors in your application.
class CustomError extends Error {
constructor(message) {
super(message);
this.name = "CustomError";
}
}
try {
throw new CustomError("Custom error message");
} catch (error) {
console.error(error.name); // "CustomError"
console.error(error.message); // "Custom error message"
}
- try...catch: Used to handle exceptions within a block of code.
- throw: Used to throw custom errors.
- Error Object: Represents an error and provides information about it.
- Specific Error Types: Built-in error types like
SyntaxError
,TypeError
, etc. - finally Block: Executes code regardless of errors.
- Global Error Handling: Catch unhandled errors globally.
- Asynchronous Error Handling: Handle errors in asynchronous code using promises or async/await.
- Custom Error Handling: Define custom error types for specific error scenarios.
By effectively using these error handling techniques, you can create JavaScript applications that gracefully handle errors and provide a better user experience.
- **Syntax:** The set of rules that dictate how programs written in a language should be structured (grammar).
- **Semantics:** The meaning and interpretation of those syntactically correct programs.
- Adding comments to explain code for better understanding, and documenting code to provide information for users and other developers.
Programming paradigms, such as procedural, object-oriented, and functional programming, provide a conceptual framework for organizing and writing code.
JavaScript is a versatile language that supports multiple programming paradigms, allowing developers to choose the approach that best suits their needs. Here are some of the main programming paradigms supported by JavaScript:
Imperative programming focuses on describing how a program operates by providing a sequence of statements that change the program's state. It emphasizes the use of statements such as loops, conditionals, and assignments.
Example:
let x = 0;
for (let i = 1; i <= 10; i++) {
x += i;
}
console.log(x); // Output: 55
Functional programming treats computation as the evaluation of mathematical functions and avoids changing state and mutable data. Functions are first-class citizens, meaning they can be assigned to variables, passed as arguments, and returned from other functions.
Example:
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce(
(accumulator, currentValue) => accumulator + currentValue,
0
);
console.log(sum); // Output: 15
JavaScript supports OOP principles such as encapsulation, inheritance, and polymorphism. Objects are used to model real-world entities, and classes provide blueprints for creating objects.
Example:
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a noise.`);
}
}
class Dog extends Animal {
speak() {
console.log(`${this.name} barks.`);
}
}
const dog = new Dog("Rex");
dog.speak(); // Output: Rex barks.
JavaScript is inherently prototype-based, meaning objects can inherit properties and methods directly from other objects, called prototypes. This allows for dynamic object creation and modification.
Example:
const personPrototype = {
greet() {
console.log(`Hello, ${this.name}!`);
},
};
const person1 = Object.create(personPrototype);
person1.name = "Alice";
person1.greet(); // Output: Hello, Alice!
Event-driven programming focuses on responding to events triggered by user actions or system events. It involves defining event handlers or listeners to handle these events.
Example:
document.getElementById("myButton").addEventListener("click", function () {
console.log("Button clicked!");
});
JavaScript is designed to handle asynchronous operations efficiently, using callbacks, promises, or async/await syntax. Asynchronous programming is essential for handling I/O operations without blocking the main execution thread.
Example:
fetch("https://api.example.com/data")
.then((response) => response.json())
.then((data) => console.log(data))
.catch((error) => console.error("Error fetching data:", error));
JavaScript supports a wide range of programming paradigms, including imperative, functional, object-oriented, prototype-based, event-driven, and asynchronous programming. Developers can choose the paradigm or combination of paradigms that best fits the requirements of their projects. This flexibility contributes to JavaScript's popularity and versatility as a programming language.
Understanding these fundamentals allows programmers to create clear, efficient, and maintainable code in any programming language. The specifics may vary between languages, but the core concepts remain consistent.
This repository is licensed under the MIT License. Your contributions are appreciated and will be openly available to the community.
Please adhere to our Code of Conduct to ensure a positive and inclusive environment for everyone.
If you have questions, suggestions, or encounter issues, feel free to open an issue. We value your feedback!
Happy coding! 🚀
Feel free to modify and customize this template according to your specific repository details and community guidelines. It's crucial to provide clear information on how users can navigate, contribute, and seek support within your open-source project.