You already know the grammar of the language: statements, blocks, valid names and strict mode. Now for the content: the data. Programming is, fundamentally, about storing information, transforming it and displaying it. In this lesson you will learn to create variables with let and const, you will understand why var belongs to the past, and you will go through every primitive data type in JavaScript. By the end you will be able to model each field of a Nómada Tasks task precisely, using the right type in every case.
Contents
- What a variable is
- Declaring variables:
letandconst varand why it is discouraged- Dynamic typing and the
typeofoperator - The
stringtype: text - The
numbertype: numbers - The
booleantype: true or false undefinedandnullsymbolandbigint- Primitives versus references
- Modeling a Nómada Tasks task
- Common Mistakes and Tips
- Exercises
- Conclusion
- What a variable is
A variable is a name associated with a value stored in memory. The usual image is a labeled box: the label is the name and the value is inside.
Three pieces:
| Piece | Function |
|---|---|
const |
The declaration keyword: it creates the variable |
assignee |
The identifier: the name you will use it by |
'Marta' |
The value that is stored |
From that line onward, writing assignee anywhere below is the same as writing 'Marta'.
It is important to understand that the variable is not the value: it is a named reference. You can change what it holds (if you declared it with let) without changing its name.
- Declaring variables:
let and const
let and constModern JavaScript offers two ways to declare variables.
2.1 const: the value is not reassigned
Two rules for const:
- You have to give it a value when you declare it.
const x;is aSyntaxError. - It cannot be reassigned afterwards.
2.2 let: the value can change
let status = 'pending';
console.log(status); // pending
status = 'in-progress';
console.log(status); // in-progress
status = 'done';
console.log(status); // donelet can be declared without an initial value; in that case the variable is undefined until you assign something to it:
let nextAssignee;
console.log(nextAssignee); // undefined
nextAssignee = 'Lucía';
console.log(nextAssignee); // Lucía2.3 Which one to use
The rule is simple and has no practical exceptions: use const by default; use let only when you know the value is going to change.
Why? Because const communicates intent. When someone reads const dueDate = ..., they know immediately that the value will not change anywhere in the function. It is free information that reduces the mental load of reading code.
// A task's id and title do not change while we are processing it
const id = 1;
const title = 'Redesign the multipurpose room';
// The status does change over the life of the task
let status = 'in-progress';2.4 A crucial nuance about const
const does not mean "the value is immutable". It means "the variable cannot be reassigned". If the value is an object or an array, its contents can still be modified:
const tags = ['design', 'space'];
tags.push('urgent'); // Allowed: we are modifying the contents
console.log(tags); // ['design', 'space', 'urgent']
// tags = ['something else']; // TypeError: cannot be reassignedThis confuses a lot of people. The explanation is in section 10 (primitives versus references) and it is developed further in Module 4.
var and why it is discouraged
var and why it is discouragedBefore ES2015 there was only var. You will find it in old code and in outdated tutorials, so it is worth knowing why it was abandoned.
3.1 Problem 1: function scope, not block scope
function reviewTasks() {
if (true) {
var message = 'With var';
let notice = 'With let';
}
console.log(message); // 'With var' — it escapes the block
// console.log(notice); // ReferenceError — it stays inside
}var ignores braces: it only respects the boundaries of a function. let and const respect any block, which is the intuitive behavior.
3.2 Problem 2: it allows redeclaration
var assignee = 'Marta';
var assignee = 'Iván'; // Allowed, without any warning
let hours = 8;
// let hours = 6; // SyntaxError: Identifier 'hours' has already been declaredRedeclaring by accident in a long file is a silent way to lose data. let warns you.
3.3 Problem 3: confusing hoisting
console.log(withVar); // undefined (it does not fail, but it misleads)
var withVar = 'value';
// console.log(withLet); // ReferenceError: Cannot access 'withLet' before initialization
let withLet = 'value';With var you get undefined instead of an error, which hides the real problem. With let you get a clear error. The mechanism is explained in Hoisting and the Execution Context.
3.4 Comparison table
| Characteristic | var |
let |
const |
|---|---|---|---|
| Scope | Function | Block | Block |
| Can be reassigned | Yes | Yes | No |
| Can be redeclared | Yes | No | No |
| Use before declaration | undefined |
ReferenceError |
ReferenceError |
| Requires an initial value | No | No | Yes |
| Creates a property on the global object | Yes | No | No |
| Recommended today | No | Yes, if it changes | Yes, by default |
Conclusion: do not write var in new code. You only need to recognize it when you see it.
- Dynamic typing and the
typeof operator
typeof operatorJavaScript is dynamically typed: variables have no type, values do. The same variable can hold values of different types throughout the program.
It is flexible, but also dangerous: nothing warns you if a variable ends up holding something other than what you expected.
To find out what type a value has, there is the typeof operator:
console.log(typeof 'Marta'); // 'string'
console.log(typeof 12); // 'number'
console.log(typeof true); // 'boolean'
console.log(typeof undefined); // 'undefined'
console.log(typeof Symbol()); // 'symbol'
console.log(typeof 10n); // 'bigint'
console.log(typeof {}); // 'object'
console.log(typeof []); // 'object' ← an array is also 'object'
console.log(typeof null); // 'object' ← the famous historical bug!The last two lines deserve attention:
typeof []returns'object'because in JavaScript an array is a special kind of object.typeof nullreturns'object'because of a bug in the very first implementation back in 1995 that has never been fixed, because fixing it would break existing code. It is the historical scar we mentioned in the first lesson.
4.1 The map of types
JavaScript has seven primitive types and one reference type (object, which covers arrays, functions, dates and so on).
flowchart TD
T["Data types in JavaScript"]
T --> P["Primitives<br/>(immutable value)"]
T --> O["Objects<br/>(reference)"]
P --> S["string"]
P --> N["number"]
P --> B["boolean"]
P --> U["undefined"]
P --> NU["null"]
P --> SY["symbol"]
P --> BI["bigint"]
O --> OB["object · array · function · Date..."]
- The
string type: text
string type: textA string is a sequence of characters: names, titles, statuses, dates in text form.
5.1 The three ways of writing text
const withSingles = 'Redesign the multipurpose room';
const withDoubles = "Redesign the multipurpose room";
const withTemplate = `Redesign the multipurpose room`;Single and double quotes are equivalent. The majority convention in JavaScript is to use single quotes, and to keep double quotes for when the text contains an apostrophe:
const note = "Marta says the workshop is not ready";
const other = 'Marta says the workshop is not ready';
const withApostrophe = "Marta's workshop is not ready"; // more comfortable with doublesYou can also escape a character with a backslash:
5.2 Template literals: the modern way
Template literals use backticks (`) and give you two superpowers.
Superpower 1: interpolation with ${}. You can insert the value of any expression inside the text:
const assignee = 'Iván';
const estimatedHours = 12;
// The old way: concatenation
const oldWay = 'Task for ' + assignee + ': ' + estimatedHours + ' hours';
// The modern way: a template literal
const modernWay = `Task for ${assignee}: ${estimatedHours} hours`;
console.log(modernWay); // Task for Iván: 12 hoursIt reads far better, and the mistakes with forgotten spaces between quotes disappear.
Any expression can go inside ${}, not just a variable:
const ivanHours = 12;
const luciaHours = 8;
console.log(`Combined workload: ${ivanHours + luciaHours} hours`); // 20 hoursSuperpower 2: real line breaks. The text is written as it is, across several lines:
const summary = `Task: Redesign the multipurpose room
Assignee: Iván
Priority: high`;
console.log(summary);With ordinary quotes you would have to use \n, which reads far worse.
5.3 Basic properties and methods
Even though string is a primitive, JavaScript lets you use properties and methods on it:
const title = 'Redesign the multipurpose room';
console.log(title.length); // 30 — number of characters
console.log(title.toUpperCase()); // REDESIGN THE MULTIPURPOSE ROOM
console.log(title.includes('room')); // true
console.log(title[0]); // 'R' — first character (position 0)One fundamental detail: strings are immutable. No method modifies the original; they all return a new one.
const original = 'pending';
const inUppercase = original.toUpperCase();
console.log(original); // 'pending' — untouched
console.log(inUppercase); // 'PENDING' — a new string
- The
number type: numbers
number type: numbersJavaScript has a single numeric type: number. It does not distinguish between integers and decimals the way other languages do.
const estimatedHours = 12; // integer
const actualHours = 12.5; // decimal
const deviation = -0.5; // negative
const almostZero = 1.5e-4; // scientific notation: 0.00015
const withSeparator = 1_000_000; // the underscore improves readability6.1 Special numeric values
There are three values that are of type number but are not ordinary numbers:
| Value | Means | How it shows up |
|---|---|---|
Infinity |
Positive infinity | 1 / 0, or a number that is too large |
-Infinity |
Negative infinity | -1 / 0 |
NaN |
Not a Number: a non-numeric result | 'high' * 2, Number('hello') |
console.log(10 / 0); // Infinity
console.log('high' * 2); // NaN
console.log(typeof NaN); // 'number' ← yes, NaN is of type numberNaN has a baffling property: it is not equal to itself.
That is why the Number.isNaN() function is used to detect it:
NaN is the typical result of a data error: someone put text where you expected a number. Seeing it in the console almost always means "check where that value came from".
6.2 Floating-point precision
This is one of every programmer's first shocks:
This is not a JavaScript bug. Numbers are stored in binary following the IEEE 754 standard, and some decimals (such as 0.1) have no exact binary representation, just as 1/3 has no exact decimal representation. Almost every language behaves the same way.
Practical solutions:
const total = 0.1 + 0.2;
// Round to as many decimals as you need
console.log(total.toFixed(2)); // '0.30' (careful: it returns a string)
console.log(Number(total.toFixed(2))); // 0.3 (a number)
// Compare with a tolerance
console.log(Math.abs(total - 0.3) < Number.EPSILON); // trueProfessional tip: for money, do not use decimals. Store cents as integers. In Nómada Tasks we will work with hours, where half a point of precision is more than enough.
6.3 Useful math operations
const hours = 12.7;
console.log(Math.round(hours)); // 13 — normal rounding
console.log(Math.floor(hours)); // 12 — down
console.log(Math.ceil(hours)); // 13 — up
console.log(Math.max(12, 8, 6)); // 12
console.log(Math.min(12, 8, 6)); // 6
- The
boolean type: true or false
boolean type: true or falseA boolean can only be true or false. It is the type of decisions.
Booleans usually come out of comparisons:
const estimatedHours = 12;
const isLongTask = estimatedHours > 8;
console.log(isLongTask); // true
console.log(typeof isLongTask); // 'boolean'Naming convention: booleans get a name that reads as a statement that is either true or false: isUrgent, isCompleted, hasTags, canBeEdited. Compare if (isCompleted) with if (completed): the first one reads by itself.
undefined and null
undefined and nullBoth represent the "absence of a value", but they are not the same, and the difference is conceptual:
undefined |
null |
|
|---|---|---|
| Meaning | "No value has been assigned" | "Deliberately empty" |
| Who sets it | JavaScript, automatically | You, explicitly |
typeof |
'undefined' |
'object' (historical bug) |
| When it appears | A variable declared without a value, a parameter that was not passed, a property that does not exist | When you decide that something is empty |
// undefined: JavaScript has nothing to put there
let nextReviewer;
console.log(nextReviewer); // undefined
// null: we are declaring that no assignee has been set
let assignee = null;
console.log(assignee); // nullThe practical distinction in Nómada Tasks: if a task does not have an assignee yet, we will use null (we know it is unassigned). If we look up a field that does not even exist, we will get undefined (there is no information).
console.log(null == undefined); // true ← loose comparison
console.log(null === undefined); // false ← strict comparisonThat contrast is the doorway into the next lesson; there you will see why it happens.
symbol and bigint
symbol and bigintThe two remaining primitives are specialized. It is enough that you know they exist.
symbol (ES2015) creates unique, unrepeatable identifiers, used above all as property keys that will not collide with others:
const key1 = Symbol('id');
const key2 = Symbol('id');
console.log(key1 === key2); // false — every symbol is uniquebigint (ES2020) lets you work with integers larger than number can represent exactly. It is written by adding n at the end:
It is useful in cryptography or for very large identifiers. We will not need it in Nómada Tasks: task ids will be ordinary numbers.
- Primitives versus references
This is the most important idea in the lesson and the one that prevents the most bugs in the long run.
Primitive values are copied by value. When you assign one primitive variable to another, the content is copied: you end up with two independent values.
let ivanHours = 12;
let luciaHours = ivanHours; // the value 12 is copied
luciaHours = 8;
console.log(ivanHours); // 12 — unaffected
console.log(luciaHours); // 8Objects and arrays are copied by reference. When you assign them, the content is not copied: what is copied is the address where the content lives. Both variables point to the same place.
const ivanTags = ['design', 'space'];
const tagsCopy = ivanTags; // the reference is copied, not the list
tagsCopy.push('urgent');
console.log(ivanTags); // ['design', 'space', 'urgent'] ← it changed too!
console.log(tagsCopy); // ['design', 'space', 'urgent']This always comes as a surprise the first time. The usual analogy: a primitive is like photocopying a document (two independent sheets of paper); an object is like handing out the address of a house (two people with the same address walk into the same house).
flowchart TD
subgraph PR["Primitives: copied by value"]
A1["ivanHours → 12"]
A2["luciaHours → 12"]
A1 -.->|independent copy| A2
end
subgraph RE["Objects: copied by reference"]
B1["ivanTags"] --> C["['design','space','urgent']"]
B2["tagsCopy"] --> C
end
And this also explains the behavior of const we saw earlier: const protects the reference, not the content it points to.
How to really copy objects (shallow and deep copies) is covered in JSON and Copying Objects. For now, hold on to the idea: primitives, a copy; objects, a shared reference.
- Modeling a Nómada Tasks task
Let's apply everything we have learned. These are the fields of a Taller Nómada task with the type that suits each one:
| Field | Type | Why that type | Example |
|---|---|---|---|
id |
number |
A sequential numeric identifier | 1 |
title |
string |
Free text | 'Redesign the multipurpose room' |
assignee |
string (or null) |
The person's name; null if unassigned |
'Iván' |
priority |
string |
One of three fixed values | 'high' |
status |
string |
One of three fixed values | 'in-progress' |
tags |
array of string |
Zero or more tags | ['design', 'space'] |
estimatedHours |
number |
A quantity, decimals allowed | 12 |
dueDate |
string |
An ISO date 'yyyy-mm-dd': it sorts correctly as text |
'2026-09-30' |
And here is the code, using only what we have seen in this lesson:
'use strict';
// --- Taller Nómada task 1 -----------------------------------------
const id = 1; // number
const title = 'Redesign the multipurpose room'; // string
const assignee = 'Iván'; // string
const priority = 'high'; // string
let status = 'in-progress'; // string (it will change: let)
const tags = ['design', 'space']; // array of strings
const estimatedHours = 12; // number
const dueDate = '2026-09-30'; // ISO string
// A derived value, calculated from the others
const isLongTask = estimatedHours > 8; // boolean
// We do not know yet who will review it
const reviewer = null; // null: empty on purpose
// A summary with template literals
console.log(`[${id}] ${title}`);
console.log(`Assignee: ${assignee} · Priority: ${priority}`);
console.log(`Status: ${status} · ${estimatedHours} h · Due: ${dueDate}`);
console.log(`Tags: ${tags.join(', ')}`);
console.log(`Long task? ${isLongTask}`);
console.log(`Assigned reviewer: ${reviewer}`);Output:
[1] Redesign the multipurpose room Assignee: Iván · Priority: high Status: in-progress · 12 h · Due: 2026-09-30 Tags: design, space Long task? true Assigned reviewer: null
Design decisions worth understanding:
statusis aletbecause a task goes from'pending'to'in-progress'and then to'done'. Everything else isconst.dueDateis astring, not aDateobject. The ISO formatyyyy-mm-ddhas a very practical property: sorted alphabetically it matches chronological order. That simplifies the work enormously.isLongTaskis not data: it is a calculation. It is derived fromestimatedHours. It is not stored as a field of the task.reviewerisnull, notundefined. We are stating that there is no reviewer, not that we know nothing about the matter.
Right now these are eight separate variables, which is awkward once you have three tasks to handle. In Module 4 you will learn to group them into an object, which is how they will really live in Nómada Tasks.
Common Mistakes and Tips
Common mistakes
- Believing that
constfreezes the contents. It protects the variable against reassignment, not the object it points to. - Using
letby default. Always start withconstand switch toletonly when your mental compiler says "this changes". - Confusing the number
12with the string'12'. They look the same in the console but behave very differently:12 + 12is24,'12' + '12'is'1212'. The next lesson is devoted to this. - Comparing decimals with
===.0.1 + 0.2 === 0.3isfalse. UsetoFixedor a tolerance. - Comparing against
NaN.NaN === NaNisfalse. UseNumber.isNaN(). - Using
nullandundefinedinterchangeably.undefinedis set by JavaScript;nullis set by you. Keep the distinction and your code will say more. - Copying an array and expecting independence.
const copy = original;copies nothing: it shares the same list.
Tips
constby default,letwhen it changes,varnever.- Use template literals for any text that combines variables. Fewer mistakes and better readability.
- Name booleans as statements of fact:
isUrgent,isDone,hasReviewer. - Use
typeofwhenever something behaves strangely. Aconsole.log(typeof x, x)solves half of all mysteries. - Store dates in the ISO format
'yyyy-mm-dd'. They sort themselves and read the same in any country. - Be careful with decimals in money and percentages. Round when displaying, not when calculating.
Exercises
Exercise 1: Choose the right type
For each piece of Taller Nómada data, state the most suitable type, whether you would use let or const, and write the line of code:
- A task's identifier, which is 7 and will not change.
- The number of pending tasks, which will vary.
- Whether the screen-printing workshop is booked for Thursday.
- The name of the person who will review the task, not yet decided.
- The team's maximum weekly hours: 40, a fixed configuration value.
- The hours spent so far, which are 3.5 and will increase.
Exercise 2: Predict the output
Without running the code, write what each line prints and explain why:
let ivanHours = 12;
let luciaHours = ivanHours;
luciaHours = 8;
console.log(ivanHours, luciaHours); // A
const tags = ['design'];
const copy = tags;
copy.push('urgent');
console.log(tags.length); // B
console.log(typeof null); // C
console.log(typeof NaN); // D
console.log(0.1 + 0.2 === 0.3); // E
const title = 'Review the invoices';
title.toUpperCase();
console.log(title); // F
let reviewer;
console.log(reviewer === null); // GExercise 3: A complete card with template literals
Write a script that declares, with the right type and keyword, every field of this task:
- id: 4
- Title:
Set up the autumn exhibition - Assignee:
Lucía - Priority:
medium - Status:
pending(it will be able to change) - Tags:
setup,event - Estimated hours: 7.5
- Due date:
2026-11-05
Then calculate and display:
- A header with the id and the title, using a template literal.
- A line with the assignee, the priority and the status.
- A boolean
isLongTask(more than 8 hours) displayed as text. - The number of tags.
- The title in uppercase, then checking that the original is still untouched.
- The type of
estimatedHoursand ofdueDate, usingtypeof.
Solutions
Exercise 1
| # | Type | Keyword | Code |
|---|---|---|---|
| 1 | number |
const |
const id = 7; |
| 2 | number |
let |
let pendingTasks = 5; |
| 3 | boolean |
const |
const isBookedForThursday = true; |
| 4 | null |
let |
let reviewer = null; |
| 5 | number |
const |
const MAX_WEEKLY_HOURS = 40; |
| 6 | number |
let |
let hoursSpent = 3.5; |
Case 4 deserves a comment: we use null because we know there is no reviewer assigned, and let because there will be one later. Case 5 goes in UPPER_SNAKE_CASE because it is a global configuration constant.
Exercise 2
| Line | Output | Explanation |
|---|---|---|
| A | 12 8 |
Numbers are primitives: assigning copies the value, so they stay independent |
| B | 2 |
Arrays are copied by reference: copy and tags are the same list |
| C | 'object' |
A historical bug from 1995 that was never fixed, for compatibility reasons |
| D | 'number' |
NaN is of type number: it represents an invalid numeric result |
| E | false |
0.1 + 0.2 gives 0.30000000000000004 because of the IEEE 754 binary representation |
| F | 'Review the invoices' |
Strings are immutable: toUpperCase() returns a new one, which is discarded here |
| G | false |
reviewer is undefined, and undefined === null is false (different types) |
Exercise 3
'use strict';
// --- Task data ----------------------------------------------------
const id = 4;
const title = 'Set up the autumn exhibition';
const assignee = 'Lucía';
const priority = 'medium';
let status = 'pending'; // let: it will change over time
const tags = ['setup', 'event'];
const estimatedHours = 7.5;
const dueDate = '2026-11-05';
// --- Derived values -----------------------------------------------
const isLongTask = estimatedHours > 8; // false
const uppercaseTitle = title.toUpperCase();
// --- Output --------------------------------------------------------
console.log(`[${id}] ${title}`);
console.log(`Assignee: ${assignee} · Priority: ${priority} · Status: ${status}`);
console.log(`Long task? ${isLongTask} (${estimatedHours} h, due ${dueDate})`);
console.log(`Tags (${tags.length}): ${tags.join(', ')}`);
console.log(`In uppercase: ${uppercaseTitle}`);
console.log(`Original untouched: ${title}`);
console.log(`Type of estimatedHours: ${typeof estimatedHours}`);
console.log(`Type of dueDate: ${typeof dueDate}`);Output:
[4] Set up the autumn exhibition Assignee: Lucía · Priority: medium · Status: pending Long task? false (7.5 h, due 2026-11-05) Tags (2): setup, event In uppercase: SET UP THE AUTUMN EXHIBITION Original untouched: Set up the autumn exhibition Type of estimatedHours: number Type of dueDate: string
Notice the last line: dueDate is a string, not a date type. It is a deliberate decision for the project and we will keep it throughout the course.
Conclusion
You now know how to store information. You declare variables with const by default and let when the value changes, and you understand why var belongs to the past (function scope, allowed redeclaration and misleading hoisting). You know about dynamic typing and the typeof operator, with its two famous quirks (typeof null and typeof [] both return 'object'). You have a command of the primitives: string with its template literals and ${} interpolation, number with NaN, Infinity and floating-point precision, boolean, the distinction between undefined and null, and the existence of symbol and bigint. And you have understood the difference between copying by value (primitives) and copying by reference (objects and arrays), which explains why const does not freeze an array.
Above all, you have modeled a complete Nómada Tasks task for the first time, choosing the right type for every field.
Now that you have data, the natural next step is to operate on it. In the next lesson, Basic Operators, you will learn to add up hours, calculate progress percentages, combine logical conditions and use modern operators such as ?? and ?.. With them you will work out the real workload of Marta, Iván and Lucía.
JavaScript Course: From Beginner to Advanced
Module 1: Introduction to JavaScript
- What Is JavaScript?
- Setting Up Your Development Environment
- Your First JavaScript Program
- JavaScript Syntax and Basic Concepts
- Variables and Data Types
- Basic Operators
- Type Conversion and Comparisons
- The Course Project: Nómada Tasks
Module 2: Control Structures
- Conditional Statements
- Loops: for, while, do-while
- Switch Statements
- Flow Control: break, continue and Nested Loops
- Error Handling with try-catch
Module 3: Functions
- Defining and Calling Functions
- Function Expressions and Arrow Functions
- Parameters and Return Values
- Scope and Closures
- Hoisting and the Execution Context
- Higher-Order Functions
- Recursion
Module 4: Objects and Arrays
- Introduction to Objects
- Object Methods and the
thisKeyword - Arrays: Basics and Methods
- Iterating over Arrays
- Searching, Sorting and Aggregating Data: find, sort and reduce
- Array Destructuring
- Object Destructuring, Spread and Rest
- JSON and Copying Objects
Module 5: Advanced Objects and Functions
- Prototypes and Inheritance
- Classes and Object-Oriented Programming
- Encapsulation: Getters, Setters and Private Fields
- Modules: Import and Export
- Asynchronous JavaScript: Callbacks
- Promises and Async/Await
- The Event Loop and the Microtask Queue
- Iterators and Generators
Module 6: The Document Object Model (DOM)
- Introduction to the DOM
- Selecting and Manipulating DOM Elements
- Handling Events
- Propagation, Delegation and Custom Events
- Creating and Removing DOM Elements
- Rendering Lists and HTML Templates
- Handling and Validating Forms
Module 7: Browser APIs and Advanced Topics
- Local and Session Storage
- The Fetch API and AJAX
- Robust Requests: Errors, Timeouts and AbortController
- WebSockets
- Service Workers and Progressive Web Apps (PWAs)
- Essential Browser APIs
- Introduction to WebAssembly
Module 8: Testing and Debugging
- Debugging JavaScript
- Code Quality: ESLint, Prettier and Conventions
- Unit Testing with Jest
- Test Doubles: Mocks, Stubs and Spies
- Integration Testing
- End-to-End Testing with Cypress
Module 9: Performance and Optimization
- Measure Before You Optimize: DevTools and Web Vitals
- Optimizing JavaScript Performance
- Memory Management
- Efficient DOM Manipulation
- Lazy Loading and Code Splitting
Module 10: JavaScript Frameworks and Libraries
- Why Frameworks Exist
- Introduction to React
- State Management with Redux
- Vue.js Basics
- Angular Basics
- Choosing the Right Framework
