The JavaScript Roadmap

After myriad research, i tried to come up with a generalist roadmap, that gradually build from the ground up. We can pick a topic weekly and dive deep, but very deep in it.

We don't have to follow it of course, we can just use it as a guideline

Feel free to alter, or propose a completely new path.

Foundational Review

  1. JavaScript Basics

    • ✅ Variables, Data Types, and Operators
    • ✅ Control Structures: if-else, switch, loops
    • ✅ Functions: Declaration, Expressions, Arrow Functions
    • ✅ Scope: Global vs. Local, Block Scope, Closure
    • ✅ Error Handling: try-catch, throw
  2. Advanced Data Structures

    • ✅ Arrays and Array Methods
    • Objects and Prototypes
    • Maps, Sets
    • Destructuring Assignment
  3. Asynchronous JavaScript

    • Callbacks and Promises
    • Async/Await
    • Handling Asynchronous Errors

Deep Dives

  1. Functional Programming in JavaScript

    • Pure Functions
    • Higher-order Functions
    • Functional Composition
    • Immutability
  2. Object-Oriented Programming (OOP)

    • Classes and Instances
    • Inheritance and Polymorphism
    • Encapsulation and Abstraction
    • Design Patterns in JavaScript
  3. Advanced Concepts

    • Event Loop and Concurrency Model
    • Memory Management and Garbage Collection
    • Memoization
    • Metaprogramming (Reflection and Proxy)
    • Modules and Namespaces
    • Inversion of Control

Typescrip

-

DOM API

Modern JavaScript Ecosystem

  1. ES6 and Beyond

    • New Syntax (Template Literals, Spread Operator)
    • New Features (Generators, Symbols, Iterators)
    • ES6 Modules
    • Updates in ES7, ES8, and beyond
  2. Tooling and Environment

    • Node.js Fundamentals
    • NPM and Package Management
    • Webpack, Babel, and Transpilation
    • Linters and Formatters (ESLint, Prettier)
  3. Frontend Frameworks and Libraries

    • React.js (including Hooks and Context API)
    • Vue.js or Angular
    • State Management (Redux, Vuex)
    • Unit Testing (Jest, Mocha)
  4. Backend with JavaScript

    • Express.js and Node.js for Backend Development
    • RESTful API Development
    • Authentication and Authorization
    • GraphQL

Advanced Topics

  1. Performance Optimization

    • Browser Rendering Optimization
    • Network Performance (HTTP/2, WebSockets)
    • Code Splitting and Lazy Loading
  2. Security Practices

    • Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF)
    • Secure HTTP Headers
    • JWT and OAuth
  3. Best Practices and Patterns

    • Clean Code Principles
    • Software Design Patterns
    • Code Review Practices
    • Refactoring Techniques

Continuous Learning

  1. Keeping Up-to-Date

    • Following JavaScript Blogs and Podcasts
    • Contributing to Open Source Projects
    • Attending Webinars and Conferences
  2. Soft Skills

    • Effective Communication
    • Leadership and Mentorship
    • Agile and Scrum Methodologies

Practical Application

  1. Project Work

    • Building Full-Stack Applications
    • Collaborative Projects with Version Control (Git)
    • Portfolio Development
  2. Interview Preparation

    • Algorithm and Data Structure Challenges
    • System Design
    • Behavioral Interview Techniques

Session Questions

Session 1

  • 🔖 Dynamic and Weekly types

    • 💡 JavaScript is a dynamic language with dynamic types. Variables in JavaScript are not directly associated with any particular value type, and any variable can be assigned (and re-assigned) values of all types:

    • 💡 JavaScript is also a weakly typed language, which means it allows implicit type conversion when an operation involves mismatched types, instead of throwing type errors.

  • 🔖 What Is meant by the term Arity

    • Arity: is a term used in computer science and mathematics to describe the number of arguments or parameters that a function or operation can accept. It’s essentially a measure of the function’s parameter count.

QA

1. Variables, Data Types, and Operators:

Question 1:

Explain the differences between null and undefined in JavaScript. Provide examples of scenarios where each would be used.

Answer:

null is an intentional absence of any object value, while undefined is typically the default value for uninitialized variables. Examples:

let a // undefined by default
let b = null // explicitly set to null

Question 2:

What is the result of the expression 5 + '5' in JavaScript? Explain the type coercion that occurs.

Answer:

The result is the string '55'. JavaScript performs type coercion, converting the number 5 to a string and then concatenating it with the string '5'.

2. Control Structures: if-else, switch, loops:

Question 3:

Explain the differences between for...in and for...of loops in JavaScript. Provide examples to illustrate their usage.

Answer:

for...in iterates over the enumerable properties of an object, while for...of iterates over iterable objects like arrays or strings. Example:

const arr = [1, 2, 3];
 
for (let index in arr) {
  console.log(index); // Outputs: 0, 1, 2
}
 
for (let value of arr) {
  console.log(value); // Outputs: 1, 2, 3
 

Question 4:

How does the switch statement work in JavaScript, and what are its advantages over multiple if...else statements?

Answer:

The switch statement evaluates an expression and matches its value against possible case values. It provides a more readable alternative to multiple if...else statements. Example:

let day = "Monday"
 
switch (day) {
  case "Monday":
    console.log("It's the start of the week.")
    break
  // Other cases...
  default:
    console.log("It's not a valid day.")
}

3. Functions: Declaration, Expressions, Arrow Functions:

Question 5:

Explain the concept of hoisting in JavaScript and how it applies to function declarations and expressions.

Answer:

Hoisting is JavaScript’s behavior of moving variable and function declarations to the top of their containing scope during the compilation phase. Function declarations are hoisted entirely, while function expressions are hoisted only for variable declarations. Example:

console.log(add(2, 3)) // Outputs: 5
 
function add(x, y) {
  return x + y
}

Question 6:

What is the difference between function declarations and function expressions? Provide examples to illustrate.

Answer:

Function declarations are statements that define named functions, while function expressions define functions as part of an expression. Example:

// Function Declaration
function greetDeclaration(name) {
  return `Hello, ${name}!`
}
 
// Function Expression
const greetExpression = function (name) {
  return `Hello, ${name}!`
}
 
console.log(greetDeclaration("John")) // Outputs: Hello, John!
console.log(greetExpression("Jane")) // Outputs: Hello, Jane!

4. Scope: Global vs. Local, Block Scope, Closure:

Question 7:

Explain the concept of closure in JavaScript. Provide an example that demonstrates closure in a practical scenario.

Answer:

Closure is the ability of a function to retain access to variables from its outer (enclosing) scope, even after that scope has finished executing. Example:

function outer() {
  let message = "Hello"
 
  function inner() {
    console.log(message)
  }
 
  return inner
}
 
const closureFunction = outer()
closureFunction() // Outputs: Hello

Question 8:

Describe the differences between let, const, and var regarding variable scoping and reassignment in JavaScript.

Answer:
  • let: Block-scoped, allows reassignment.
  • const: Block-scoped, does not allow reassignment after declaration.
  • var: Function-scoped, allows reassignment.

5. Error Handling: try-catch, throw:

Question 9:

Explain how the try...catch statement works in JavaScript, and provide an example of using it to handle an error.

Answer:

The try...catch statement allows you to handle runtime errors in a controlled manner. Example:

function divide(a, b) {
  try {
    if (b === 0) {
      throw new Error("Division by zero is not allowed.")
    }
    return a / b
  } catch (error) {
    console.error(`Error: ${error.message}`)
    return NaN
  }
}
 
console.log(divide(10, 2)) // Outputs: 5
console.log(divide(5, 0)) // Outputs: Error: Division by zero is not allowed.

Question 10:

Explain the difference between the throw statement and console.error for handling errors in JavaScript.

Answer:
  • throw: Used to explicitly throw an exception, allowing you to create custom error messages and control error flow.
  • console.error: Outputs an error message to the console but does not

Weekly learning

Day 1

Daniel

Abstract operations

Cynthia

Penine

Copy within method

Mental Model session

What is the output of the following code snippet, and why?

function func() {
  return new Promise((resolve, reject) => {
    resolve("First")
    reject(new Error("Second"))
    resolve("Third")
  })
}
 
func()
  .then((result) => console.log(result))
  .catch((error) => console.error(error.message))
Answer

The output is 'First'. This happens because even though resolve('First') and reject(new Error('Second')) are both called synchronously within the executor function of the Promise, only the first call is effective. Once a promise settles (either resolves or rejects), it cannot change its state.

  1. What is the DOM (Document Object Model) and how does it relate to HTML?

    • Answer: The DOM is a programming interface for web documents. It represents the structure of an HTML or XML document as a tree of objects, where each object corresponds to a part of the document, such as elements, attributes, and text. It provides a way for programs to dynamically access and manipulate the content, structure, and style of web documents.
  2. Explain the differences between innerHTML, innerText, and textContent.

    • Answer:
      • innerHTML: Represents the HTML content of an element as a string. It can be used to both retrieve and update the HTML content, including HTML tags.
      • innerText: Represents the text content of an element, excluding HTML tags. It returns only the visible text content and ignores any elements inside the element.
      • textContent: Represents the text content of an element, including all elements and their text content. It returns the text content of an element and all its descendants, without any HTML formatting.
  3. What are event bubbling and event capturing in the DOM?

    • Answer:
      • Event Bubbling: Event bubbling is the process where an event triggered on a child element is propagated up through its parent elements in the DOM tree. This means that the event starts from the target element and bubbles up through its ancestors.
      • Event Capturing: Event capturing is the reverse of event bubbling. It involves capturing an event at the highest level of the DOM tree first and then propagating it down to the target element. This phase occurs before the actual event reaches the target element.
  4. How does event delegation work in the DOM, and what are its benefits?

    • Answer: Event delegation is a technique where you attach an event listener to a parent element rather than to its children. When an event occurs, it bubbles up to the parent element, where you can check the event target to determine which child element triggered the event. This approach is beneficial for dynamically created elements or elements with similar behavior, as it reduces the number of event listeners needed and improves performance.
  5. Explain the concept of the DOMContentLoaded event. When does it fire, and why is it useful?

    • Answer: The DOMContentLoaded event fires when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading. It’s useful for executing JavaScript code that depends on the DOM being fully loaded, such as manipulating DOM elements, attaching event listeners, or fetching additional resources.
  6. What are data attributes (data-*) in HTML, and how can they be accessed and manipulated using JavaScript?

    • Answer: Data attributes (data-*) are custom attributes that can be added to HTML elements to store additional information. They are prefixed with data- followed by a descriptive name. These attributes can be accessed and manipulated using JavaScript through the dataset property of the element. For example, if you have a data-id attribute on an element, you can access it as element.dataset.id.
  7. Explain the purpose and usage of the querySelector and querySelectorAll methods in the DOM.

    • Answer:
      • querySelector: This method returns the first element within the document that matches the specified CSS selector. If no matches are found, it returns null. It’s commonly used to select and manipulate single elements based on their CSS selector.
      • querySelectorAll: This method returns a static NodeList representing a list of elements within the document that match the specified CSS selector. It allows you to select multiple elements and iterate over them using methods like forEach or indexing.

Though symbols are unique , there is actually a way of crating non unique symbols, meaning , if a symbol has the same name, then it is gonna be used instead. what is that way ?

Using Symbol for:

const s = Symbol.for("name")
const newS = Symbol.for("name")
const person = {
  age: 25,
  [s]: "Male",
}
console.log(person[newS])

Threads of Execution

#Execution JS is not that fancy, it goes though our code line by line, and does run/execute each line known as thread of execution. It threads it’s way down the code as it goes.

  • ➡️ It also save data like strings and arrays so we can use the data later on. (it stores the data in the memory.)

Threads simply takes the code, run it over and over again line by line. (it's simply the ability of going over line by line and do execute the lines.)

const num = 3
function multiplyBy2(inputNumber) {
  const result = inputNumber * 2
  return result
}
const output = multiplyBy2(num)
const newOutput = multiplyBy2(10)
/* 
What will happend i that the first line will run, then create a variable called num and assign it to 3
 
Then what will follow is that the second line will run which will simply store our function in th ememory for letter usage 
 
Our line 4 which create a new variable output, must store a given value, and for that js creates a new execution context, that will simply run the mini program(which in this case is our function(multiplyBy2))
after js has created a new execution contect, it will run that function in that execution context and the returned value will be assigned to the outout constant 
 
same for the newOutput too, a new execution context will be created. 
*/

What is Event Delegation

Event Delegation is a pattern based upon the concept of Event Bubbling. It is an event-handling pattern that allows you to handle events at a higher level in the DOM tree other than the level where the event was first received.

Event delegation is a technique in JavaScript where instead of attaching event listeners to individual elements, you attach a single event listener to a parent element. This allows you to handle events that occur on child elements without needing to attach separate listeners to each child.

Why event delegation ?

  • 💡 Event delegation is a technique that allows you to handle events on parent elements instead of attaching listeners to individual child elements.
  • 💡 To implement event delegation, attach a single event listener to a parent element and use the event.target property to determine the specific child element that triggered the event.
  • 💡 Event delegation is particularly useful for handling events on dynamically created or large sets of elements, improving performance and memory efficiency.

The term “lexically scoped language” refers to the scoping rules of a programming language, specifically how variables are resolved and accessed within nested functions or blocks of code. In the context of JavaScript, being lexically scoped means that variable access is determined by the location of the variables within the source code (the lexical structure), rather than by the runtime flow of the program.

Mental model session

  • How do you define read only property on objects
  • What is the use of a heap
  • What is the difference between callback and promises and where are they used ?
  • write a program that swaps two variables using destructuring ?