Understanding JavaScript: The Essential Browser Language

Understanding JavaScript: The Essential Browser Language

JavaScript💻

It is the programming language of the Web & was invented by Brendan Eich in the year 1995


Basic Concepts🤗

Variables and data types

Variables are containers for storing data values. Data types include primitives like strings, numbers, Booleans, and more complex types like arrays and objects.

  • Variables - there are three types of variables are var , let & const

Let us see the table to check the purposes of different variables

VariablesScopeRedeclareReassignHoistedBind This
varGlobalYesYesYesYes
letBlockNoYesNoNo
constBlockNoNoNoNo

Scope - refers to the visibility and accessibility of variables
Redeclare - In JavaScript, using var, you can accidentally or intentionally declare the same variable multiple times within the same scope without causing an error. However, redeclaring a variable using let or const in the same scope will result in an error.

Reassign - refers to assigning a new value to an existing variable.

Hoisted - a JavaScript mechanism where variables and function declarations are moved to the top of their containing scope during the compile phase before the code execution
Bind This - allows you to explicitly set the value of this for a function when it is invoked. It creates a new function with the specified this value and optionally initial arguments.

  • Data Types - there are two types of data types primitive and non-primitive data type
  1. Primitive Datatypes
  • String - used for Storing text & is written with quotes. Ex- let text = "John Doe";

  • Number - Javascript has Only one type of Number & can be written, with or without decimals. Ex-

    let x= 3.14; // no with decimal

    let y= 42; // no without decimal

  • Big Int - It is used to store big integer values that are too big to be represented by a JS Number. Ex- let Z= 48799999999;

  • Booleans - A JS Boolean represents one of 2 values True or False. Ex -

    let isLogged = true;

    let isValid = false;

  • Undefined - a variable has not been assigned a value or not declared at all. Ex -let x;
    let y = undefined;

  • Null - It represents the intentional absence of an object value. Ex - let user = null;

  1. Non-Primitive Datatypes
  • Object - Js objects are written with curly braces `{ }` in name & value pairs separated by commas.

    Ex - {firstName : "John" , lastName : "Doe" , age : 50};

  • Arrays - Js arrays are written with square brace `[ ]` & commas separate array items.

    Ex - let fruits = [apple , grapes , banana , litchi]

Operators

Symbols are used to perform operations on variables and values. Examples include arithmetic operators (+, -, *, /), comparison operators (>, <, ===), and logical operators (&&, ||).

  1. Arithmetic Operators - These Operations perform arithmetic on numbers(literals or variables).

  2. A chart displaying operators and their respective names: Addition (+), Subtraction (-), Multiplication (*), Exponentiation (**), Division (/), Remainder (%), Pre increment (++), Post increment (++), Pre decrement (--), Post decrement (--).

    Comparison Operator - used in logical statements to determine equality or difference between variables or values and also used to test for boolean values.

  3. Logical Operator - Used to determine the logic between variables or values.

  4. Assignment Operator - Helps to assign values to JS variables.

Control statements

Control the flow of execution in a program. if statements perform conditional execution, while loops (like for and while) Repeat the code until a condition is met.

  1. if Statement - specify a block of code to be executed if a specified condition Is true.

     if(hour < 18){
     greeting = "Good Day";;
     }
    
  2. else Statement - specify a block of code to be executed, if the same condition is false.

     if(hour < 18){
     greeting = "Good Day";}
     else{
     greeting = "Good Evening";
     }
    
  3. else if Statement - specify a new condition to test, if the first condition is false.

     if(time < 10){
     greeting = "Good Morning";}
     else if(time < 20){
     greeting = "Good Day";}
     else{
     greeting = "Good Evening";
     }
    
  4. switch - It specifies many blocks of code to be executed.

     switch(new Date().getDay()){
     case 0 :
     day = "sunday";
     break;
     case 1:
     day = "Monday";
     break;
     case 2:
     day = "Tuesday";
     break;
    

Loops

  1. for - loops through a block of code several times.

     let text = ""
     for(let i= 0 ; i <5; i++){
     text += "The number is " + " i"</br>";
     }
    
  2. while - loops through a block of code while a specified condition is true.

     let text = ""
     while( i < 10){
     text += "The number is " + i;
     i++ ;
     }
    
  3. do/while - loop will always be executed at least once, even if the condition is false, then repeat the loop as long as the condition is true.

     let text = ""
     do {
     text += "The number is " + i;
     i++ ;
     }
     while(i < 10)
    
  4. for in - loops through the properties of the object.

     const person = { fname : "john" , lname : "doe" , age : 25};
    
     let text = "";
     for (let x in person){
     text += person[x];
     }
    
  5. for of - It loops through the value of an iterable object like arrays, strings, maps, and node lists.

Functions

  1. Function Declaration - It is used to define a reusable block of code, consisting of the function keyword, name, and optional parameters & they are hoisted.

  2. Function expressions - assign a function to a variable. it's created using a function keyword followed by optional parameters in parentheses & the function body in curly braces.

  3. Parameters & Arguments -

    Parameters - These are placeholders within a function parenthesis that represent the values that a function expects to receive when calling.

    Arguments - these are the actual values passed to the function when it's invoked. here (no. of arguments = no of parameters).

  4. Default Parameters - allow us to tell default values for function parameters in case no arguments are provided for those parameters during a function call.

  5. Return Statement - It is used to specify the value a function should return after its execution.

Arrays

Creating & Accessing arrays - We have 2 ways to create an array

  1. Array Literals - we use square brackets [] & list the elements separated by commas.
const fruits = ["Banana","orange","mango"];
  1. Array Constructor - This method uses an Array() constructor & can optionally pass arguments to specify the initial length of the array or provide the elements directly.

Accessing Elements - Arrays are ordered collections & elements are accessed using their index, which starts from 0.

Array Methods - (push, pop, shift, unshift, slice, splice)

  1. push() - Add an element at the end of an array, modify the original array, and return the new length of the array.

  2. pop() - Remove the last element from an array, modify the original array also return the removed element.

  3. shift() - remove the first element from an array, and modify the original array. also, return the removed element.

  4. unshift() - Add elements at the beginning of an array, modify the original arrays, and return the new length.

  5. slice() - extracts a section of the array & returns a new array containing the extracted elements.

  6. splice() - remove elements by specifying a start index & number of elements to remove & Add elements by providing new elements after a start index & Replace elements by providing new elements, start index, and no. of elements to replace. It also modifies the original array.

Objects

Creating Objects - There are 2 ways to create an object in JS

  1. Object Literals - we use square brackets { } & list the elements separated by commas in name & value pair separated by colon(:).

  2. Object Constructor - this method is less common but offers more flexibility, we can create objects using new Object()

Accessing Properties & Methods

  1. Dot Notation - use a dot(.) to access object properties & methods

  2. Bracket Notation - use square brackets [] to access properties dynamically or with variable names

Nested Objects

Objects can contain other objects within them, creating a hierarchical structure

Basic Error Handling

  1. try, catch, finally
  • try - this block encloses code that you anticipate might throw errors

  • catch - this block executes if an error occurs within the try block. It receives an error object (usually named err) containing details about the error including its type. (err.name) & message (err. message)

  • finally - This block executes unconditionally, whether or not an error occurs in the try block. It's commonly used for cleanup tasks like closing resources

  1. Custom errors

    Using an error constructor or its built-in sub-class like type error, reference error, etc & these objects can have properties like name & message


Javascript Fundamental🔥

Let vs const vs var

  1. var (avoided in modern JS) - It is a function scope/globally scoped if declared outside of any functions & it can be re-declared & updated within its scope.

  2. let (recommended)- It's a block-scoped, A block can be an if statement, for loop or any code wrapped in {} & it can be updated but not re-declared within its scope.

  3. const (recommended in modern JS) - It is block-scoped similar to let & it cannot be updated to re-declared after initialization.

Truthy & Falsy values

In JS, certain values are considered "truthy" when evaluated in a boolean context(like conditions in an if statement), while others are false

  1. Truthy values
  • true (of course!)

  • Any non-zero no.(including +ve , -ve & floating point)

  • Non-empty strings (including strings with just spaces or special characters)

  • Objects (including empty objects { })

  • Arrays(including empty array [])

  • Functions

  • NaN(Not a Number)

  1. False values
  • false

  • 0 (Zero)

  • -0 (-ve zero)

  • " " (empty string)

  • ' ' (empty single quotes)

  • null (represents no value)

  • undefined (variable declared but not assigned)

Short Circuit Evaluation

JS uses short-circuit evaluation in logical opis (&&-AND, ||-OR). This means that when evaluating a Condition with multiple expressions joined by these operations, it stops evaluating as soon as it can determine the outcome based on truthy/falsy value.

  1. AND(&&) -

    If the 1st expression is falsy, the entire condition is falsy & the 2nd exp isn't evaluated.

    If the 1st exp is true, it continues evaluating the 2nd exp (bcz the overall result might still depend on it).

     Example 1
    
     if (false && "Hello") 
     { // ist exp is falsy, so the 2nd isn't evaluated 
     Console.log("This won't print!");
     }
    
     Example 2
    
     if (true || "word"){
     // 1st exp is truthy , so the 2nd does'nt matter
     console.log("This will print (OR)");}
    
  2. OR(||) -
    If the 1st exp is truthy, the entire Condition is truthy & the 2nd exp isn't evaluated

    If the 1st exp is falsy, it continues evaluating the 2nd exp bcz the overall result might still be true based on the 2nd exp)

     Example 1
    
     if (false 11 "Bonjour") 
     {// 1st is falay, but and is truthy, So overall truthy 
     Console.log(" This will font (OR)"); 
     }
    
     Example 2
    
     if (true || "Hola"){
      // 1st is truthy, so the 2nd doesn't matter 
     Console.log("This will Point (OR)");
     }
    

Type Equality & Coercion

  1. Type Equality - This refers to whatever two values have the same data type (no., string, boolean, etc)

    JS uses 2 equality operators:

    Strict equality (===): Check for both type & value equality If the types are different, it returns false without any coercion

    Loose equality (==): Performs type Coercion before Comparison this can lead to surprising results.

  2. Type Coercion

    In JS, when using the loose quality Opr (==) or other comparison Opr, JS might implicitly Convert one value to the type of the other to enable Comparison. Comprovis This behaviour can be helpful but also head to unexpected outcomes if not understood.

Pass by value VS Pass by reference

  1. Pass by value - when you pass an argument (primitive value) to a function in JS, a copy of the value is passed. Any changes made inside the function don't affect the original value. this applies to primitive data types like numbers, strings, & booleans.

     function bakeCookies(sugar){
     sugar = sugar + 2; 
     console.log("sugar inside the function", sugar);
     }
     let origionalSugar = 10;
     bakeCookies(origionalSugar);
     console.log("Sugar outside the function(origional)" , origionalSugar);
    
  2. Pass by reference - when you pass an argument object or array to a function, a reference (memory location) to that object or array is passed. changes made inside the function will modify the original object or array. this is because objects & arrays are stored in memory by reference

     function buyIngredients(shoppinglist){
     shoppinglist.flour = shoppinglist.flour + 2;
     console.log("Flour inside the function(reference):" , shoppinglist )
     }
     let shoppingcart = { flour : 5 };
     buyIngredients(shoppingcart);
     console.log("Flour outside the function(origional):" shoppingcart.flour);
    

Advanced Array Methods

  1. for Each() - executes a provided for one for each array element. It doesn't return a new array

     Example -
     Const fruits = ["apple", "barara", "Orange"]; 
     fruits.forEach(fruit => Console.log(fruit)); // logs each fruit one a new line
    
  2. map() - creates a new array with the results of calling a provided function on every element in the original array

     Example -
     Const number = [1,2,3];
     Const doubleNumbers = numbers.map(number => number * 2); // [2,4,6]
    
  3. filter() - Creates with elements that Pass by a test implemented by the provided function

     Example  -
     Const ages = [20, 18, 35, 16];
     Const adults = ages.filter(age => ages >= 18); // [20, 18 , 35]
     console.log(adults);
    
  4. reduce() - Applies a function against an accumulator & each element in the array to reduce it to a single value.

     Example -
     Const items = [10,5,2];
     Const total = items.reduce((accumulator, current) => accumulator + current, 0)
     Console.log(total);
    

Advanced Functions & Objects📢

Function Hoisting

In JS, function declarations (but not on expression) are hoisted to the top of their Scope (usually the global scope or the scope of a function block). This means that you can call a function before it's defined in your scope of a function block & it will still work

Example-

greet(); // This work bcz of hoisting.
function greet() { console.log("Hello!");}

IIFEs

An IIFE is a function expression that's wrapped in parentheses & then immediately invoked with another pair of parentheses, This creates an anonymous function that runs as soon as it's defined.

Example -  
(function(){
Console.log("This function runs immediately!"); })();

Closures

It is a function that has access to the variables of its outer (enclosing) function, even after the outer function has returned. This Closure remembers the environment in which it was created

Example -
function createGreeter(greeting){ 
return function(){
console.log(greeting + " ,world!");
};
}
const greetMorning = createGreeter("Good Morning");
const greetEvening = createGreeter("Good Evening");
greetMorning();
greetEvening();

Here, the Create Greeter function creates Closures. Each Closure (functions assigned to greet Morning & greet Evening) remembers the value of the greeting passed to it, even after create greeting has finished executing

Callback Functions

It is a function passed as an argument to another function. the receiving function then invokes (calls back) the callback function at a later point, typically after Some asynchronous Operation Completes. This allows for a more modular & flexible approach to handling events & asynchronous operations.

function greet(name, Callback) {
console.log("Hello", "+ name + "!"); 
callback(name);
}
function shoutName(name) {
console.log(name.touppercase() + "!!!!"); 
}
greet ("Alice", shoutName);

Constructor Functions

It is a special type of function that is used to create objects. It helps to define the properties & behaviours of Objects of a certain type. when you invoke a Constructor function with the new keyword, JS creates a new object and initializes it with the properties & methods defined in the constructor & returns a reference to the new object.

function person(name, age){
this.name = name;
this.age = age;
this.introduce = function(){
console.log("Hello, my name is" + this.name +" and I am " + this.age + "year's old")
};
}
const person1 = new person("Alice", 30);
person1.introduce();

Objects & Prototypes

  1. Object - An object in JS is a Collection of properties (Key-value pairs) that represent the data & function of the object. Properties can hold various data types like Strings, no's arrays, or even functions (method).

  2. Prototype - Each object in JS has a prototype, which is another object that acts as a blueprint for the properties & methods inherited by 1st object. JS looks for it within the object itself. If it's not found there, JS then looks for it in the object's prototype. this prototype chain allows for Code reusability & inheritance.

     Example-
     function Person(name, age){ 
     this. name = name; 
     this. age = age;
     }
     Persen.prototype.introduce = function() { 
     console.log("Hello, my name is" + this.name + "and I am" + this.age + "years old");
     };
     Const person1 = new Person("Alice", 30); 
     Const person2 = new Person("Bob", 25);
    
     Person1.introduce(); 
     Person2.intruduce();
    

Classes & Inheritance

  1. Class - classes provide a blueprint for Creating objects. They define properties (data) & methods (functions) that objects of that Class will inherit.

     class Person{
     constructor(name){
     this.name = name;
     }
     greet(){
     console.log("Hello, my name is" + this.name);
     }
     }
    
  2. Inheritance - It allows you to create new Classes (Subclasses) that inherit properties & methods from existing Classes (Parent Classes). This promotes Code reusability & Creates a hierarchy of related objects.

     class Student extends Person{
     constructor(name, major){
     super(name);
     this.major = major;
     }
     introduce(){
     console.log("I'm" + this.name + "a student majoring in" + this.major);
     }
     }
    

Functional Programming

It is a style of programming that emphasizes functions as the building blocks of application

It focuses on:-

  1. Pure Functions - functions that always return the same output for the Same input & don't produce side effects (changes outside the functions)

  2. Immutable data - Data Structures that cannot be modified after Creation. New data Structures are Created to represent changes.

  3. 1st class functions - Functions can be treated like any other value: assigned to variables, passed as arguments & returned from other functions.

OOP

It is a programming paradigm around objects that organises Code that encapsulates data (properties) & behaviour (methods). Objects interact with each other through messages (method calls)

  1. Class - classes provide a blueprint for Creating objects. They define properties (data) & methods (functions) that objects of that Class will inherit.

  2. Object - It allows you to create new Classes (Subclasses) that inherit properties & methods from existing Classes (Parent Classes). This promotes Code reusability & Creates a hierarchy of related objects.

  3. Encapsulation - Bundling data (properties) & methods together within objects to protect data integrity & control access.

  4. Inheritance - Creating new classes that inherit properties & methods from existing classes, promoting code reusability.

  5. Polymorphism - The ability of objects of different classes to respond to the same method Call in different ways.


Modern JavaScript🚀

ECMAScript

It is the standardized scripting language used by JS engines. It defines the core syntax, objects & behaviours that Javascript implements.

Understanding ECMAScript helps you write code that's compatible across different JS environments & browsers. New features are added to the standard through versions like ECMAScript 2020(ES2020) or ES6 (for ECMAScript 2015)

Examples - Features like arrow functions, let & const for variable declarations & template literals are all part of the ECMAScript standard

Symbol

They are unique primitive types in JS that represent an identifier (like a name) for an object property. They are guaranteed to be unique across your entire application, even if you create multiple symbols with the same description.

symbols are valuable for creating private properties on objects or for situations where you need truly unique identifiers that can't conflict with existing property names.

BigInt

They are relatively new data types in JS (Introduced in ES2020) that allow you to represent integers larger than the limit of the standard Number type (9 quadrillion).

BigInt is essential for working with very large numbers that would lose precision when stored as regular numbers. They are commonly used in cryptography, financial applications & scientific calculations.

Sets

It stores unique values of any data type. we can create sets in 2 ways:-

  1. const myset = new set([1,2,3,4,5,"apple"]);

  2. const myset = new set();

Methods

MethodUses
add(value)adds a value to the set (if unique)
has(value):returns true if the set contains the value, false otherwise.
delete(value):removes the value from the set if present, returns true if successful, false otherwise
size()returns the number of elements in the set.
clear()Removes all elements from the set.
values()returns an iterator object
entries()returns an iterator object containing a key-value pair (for sets, keys & values are the same)
forEach(callback)Executes a provided function once for accessing elements in a collection one at a time

Maps

It stores key-value pairs where keys can be any datatype (unlike objects limited to strings). we can create maps in 2 ways:-

  1. const myMap = new Map([["name" , "Alice"],[1, "Apple"]])

  2. const myMap = new Map(); (empty Map)

Methods

MethodUses
set(key,value)sets the value for a key
get(key)returns the value associated with the key, undefined if not found
has(key)returns true if the map
delete(key)removes the key-value pair from the map if present, returns true if successful, false otherwise
sizereturns the no. of key-value pairs in the map
clear()Removes all elements from the map
keys()returns an iterator object containing keys in the insertion order
value()returns an iterator object containing values in the insertion order
entries()returns an iterator object containing a key-value pair
forEach(callback)Executes a provided function once for accessing elements in a collection one at a time

Iterators & Generators

  1. Iterators - objects that define a protocol for accessing elements in a collection one at a time.Implements a next() method that returns an object with value (the current element) & done (boolean indicating iteration completion) properties.

    Built-in iterable like arrays, strings, sets & maps have their default iterators. used in for..of loops to iterate over iterable.

  2. Generators - Function with a yield keyword that can pause & resume execution, returning values one at a time. we can create generators with a function declared with function*

Proxy & Reflects

  1. Proxy -

    creates a virtual object that intercepts & potentially modifies fundamental operations(like property access, and method calls) performed on the target object. useful for validation, logging, data transformation & more.

  2. Reflect -

    It provides functions that mirror the internet methods used by proxy traps.

    used within proxy traps to perform the original behaviour on the target object when needed.

Other ES6+ Features (Spread, Rest, Destructing, Nullish Coalescing, optional chaining, arrow functions, modules, etc)

  1. Spread(...) Operator+ - expands iterable objects (arrays, strings) into individual elements. used for copying arrays/objects, concatenating arrays, and passing function arguments.

  2. Rest() Parameter - collects remaining arguments into an array within a function

  3. Destructing - Extracts properties/values from objects/arrays into distinct variables.

  4. Nullish Coalescing(??) Operator - returns the right-hand operand if the left-hand operand is null or undefined.

  5. Optional Chaining(?) Operator - safely accessed nested properties of an object, avoiding errors if the property chain is broken.

  6. Arrow Functions (=>) - concise syntax for defining functions, Implicit return for single-expression bodies, don't have their binding (inherit from surrounding context).

  7. Modules(import, export) - organize code into reusable modules. import to bring in functionality from other modules.


Asynchronous Programming😧

Synchronous VS Asynchronous

  1. Synchronous - code executes in a sequential order, one line at a time. the program waits for each line to finish before moving on to the next.

     console.log("Start");
     for(let i = 0 ; i < 3; i++){
     console.log(i);
     }
     console.log("End");
    
  2. Asynchronous - code execution doesn't necessarily follow a strict order. the program can initiate an operation (like fetching data from the server) & continue with other tasks while waiting for the operation to complete. when the operation finishes, a callback function is executed to handle the result.

     console.log("Start");
     setTimeout(() => {
     console.log("After 2 sec");
     },2000);
     console.log("continue...")
     })
    

JS Engine & Environment

  1. JS Engine - The core component that intercepts 7 executes JS code. It's responsible for passing code, converting it to machine code & running it on the computer. popular engines include V8 (chrome,Node.js)

  2. JS Environment - The context in which the JS engine operates. It provides objects, functions & variables that the engine can use in different environments, such as:-

    1. Browser Environment - In the context of web browsers, JavaScript runs within a browser environment. This environment includes DOM (Document Object Model), BOM (Browser Object Model), Window Object

    2. Node.js Environment - JavaScript runtime environment outside of the browser, with access to Node.js core modules, and global objects like global, and using CommonJS modules for modular code organization.

Timers

  1. setTimeout(function, milliseconds) - Executes a function after a specific no. of milliseconds.

  2. setInterval(function, milliseconds) - Executes a function repeatedly, with a fixed time delay between each execution.

  3. clearTimeout(timeoutId) - Clears a time set with setTimeout before it goes off

  4. clearInterval(intervalId) - Clears a timer set with setInterval to stop its repeated execution.

Call Stack

The call stack is a crucial concept in JavaScript’s runtime environment, representing the mechanism by which the JavaScript engine keeps track of function calls in a program. It operates as a Last In, First Out (LIFO) data structure, meaning that the last function called is the first one to be resolved.

function main() {
    console.log('Main function starts');
    subFunction();
    console.log('Main function continues');
}

function subFunction() {
    console.log('Sub-function called');
}

main();

Event Loop

The event loop is responsible for managing the execution of code in JavaScript, especially when dealing with asynchronous operations like callbacks, promises, and async/await.

How it works:

  • The event loop continuously checks the call stack and the task queue (callback queue).

  • If the call stack is empty, it takes the first callback from the queue and pushes it onto the call stack, where it begins execution.

  • This process ensures that asynchronous operations are handled non-blocking, allowing the JavaScript engine to efficiently manage multiple operations concurrently.

      console.log('Start');
    
      setTimeout(() => {
        console.log('Timeout');
      }, 2000);
    
      console.log('End');
    

Call Stack: Manages the execution context of synchronous function calls. Functions are added and executed in a Last In, First Out (LIFO) order.

Task queue & Microtask Queue

  1. Task Queue(callback queue) - The task queue (also known as the callback queue or message queue) is a queue data structure that holds tasks (or messages) waiting to be processed. These tasks are typically added to the queue by the browser APIs, such as setTimeout, setInterval, DOM events, and other asynchronous operations.

     console.log('Start');
    
     setTimeout(() => {
       console.log('Timeout');
     }, 0);
    
     console.log('End');
    
  2. Microtask Queue - The microtask queue (also known as the job queue or microtask checkpoint) is a special queue for tasks that are executed after the current task but before the event loop continues. Microtasks are often used for scheduling the execution of smaller tasks that should be prioritized over regular tasks in the task queue.

     console.log('Start');
    
     Promise.resolve().then(() => {
       console.log('Promise resolved');
     });
    
     console.log('End');
    

Callback Hell

Callback Hell occurs when you nest multiple callback functions with each other to handle the results of asynchronous operations. this leads to deeply indented code that becomes difficult to read, maintain & debug.

The example below shows Callback Hell

function getData(url, callback) {
  // Simulate asynchronous operation (like fetching data)
  setTimeout(() => {
    const data = "Fetched Data";
    callback(data);
  }, 1000);
}

getData("https://api.example.com/data", (data) => {
  console.log("Data:", data);

  processData(data, (processedData) => {
    console.log("Processed Data:", processedData);

    displayData(processedData);
  });
});

Promises

Promises offer a more structured way to handle asynchronous operations, A promise is an object representing the eventual completion(or failure) of an asynchronous task. It provides methods like .then() & .catch() operations & handle errors gracefully.

function fetchData(userId) {
  return new Promise((resolve, reject) => {
    // Simulate asynchronous operation (like fetching data)
    setTimeout(() => {
      if (userId === 1) {
        const userData = { name: "Alice", email: "alice@example.com" };
        resolve(userData); // Promise fulfilled with user data
      } else {
        reject(new Error("User not found")); // Promise rejected with error
      }
    }, 1000);
  });
}
const userId = 1;
fetchData(userId)
  .then((userData) => {
    console.log("User Data:", userData); // Handle successful data retrieval
  })
  .catch((error) => {
    console.error("Error:", error.message); // Handle errors
  });

Async/Await

Async/await is syntactic sugar built on top of promises. It allows you to write asynchronous code in a more synchronous-like style, using async & await pauses execution until the awaited promise resolves or rejects.

async function fetchData(url) {
  // Simulate asynchronous operation (like fetching data)
  const response = await fetch(url);
  const data = await response.json();
  return data;
}
async function main() {
  try {
    const url = "https://api.example.com/data"; // Replace with your actual API endpoint
    const data = await fetchData(url);
    console.log("Fetched Data:", data);
  } catch (error) {
    console.error("Error:", error.message);
  }
}
main();

Deep Dives In Js

Execution Contexts

Imagine an execution context as a container that holds information about the code currently running. It dictates what variables, functions & objects are accessible

There 2 main types of

  1. Global Execution Context - Created when your JS code starts. It holds globally declared variables (outside any function declaration)

  2. Function Execution Context - Created whenever a function is called. It holds local variables & arguments specific to that function call, along with a reference to the global scope through the scope chain

this keyword, call, Apply & bind

  • this keyword refers to the current execution context's object. Its value depends on how the function is called.

  • Apply is similar to call, but it takes arguments as an array.

  • Bind creates a new function with a pre-set value.

Static vs Dynamic Typing

  • Static Typing - variables types are declared explicitly before assignment & the compiler checks for type mismatches at compile time

  • Dynamic Typing - Variable types are determined at runtime based on the assigned value. JS is dynamically typed.


Conclusion

Thisarticle covers JavaScript concepts like variables, data types, operators, control statements, loops, functions, arrays, and objects. It covers advanced topics like error handling, modern concepts, short-circuit evaluation, type equality, and ES6+ features. Mastering JavaScript environments, event loops, call stacks, and more is crucial.Hope you find helpful☺️

Follow Me On Socials :

LinkedIn

Twitter

GitHub

Like👍|Share📲|Comment💭

Did you find this article valuable?

Support MOHD NEHAL KHAN by becoming a sponsor. Any amount is appreciated!