JavaScript
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax and Types
-
Section 3: Strings and Numbers in Depth
-
Section 4: Control Flow
-
Section 5: Functions
-
Section 6: Objects and Arrays
-
Section 7: Maps, Sets, and Symbols
-
Section 8: Asynchronous JavaScript
-
Section 9: Object-Oriented and Prototypes
-
Section 10: The DOM
-
Section 11: Browser APIs
-
Section 12: Modern JavaScript (ES2015-ES2025)
-
Section 13: Functional Programming Patterns
-
Section 14: Error Handling and Debugging
-
Section 15: Testing
-
Section 16: Accessibility for JavaScript Developers
-
Section 17: Internationalization and Localization
-
Section 18: Performance
-
Section 19: Node.js Fundamentals
-
Section 20: Regular Expressions
-
Section 21: Design Patterns in JavaScript
-
Section 22: Security Basics
-
Section 23: Data Structures and Algorithms in JavaScript
-
Section 24: Practical Projects
-
Section 25: More Advanced Async Patterns
-
Section 26: More Object and Class Practice
-
Section 27: Working with Dates and Internationalization
-
Section 28: Web Components
-
Section 29: More DOM and Browser Practice
-
Section 30: Build Tooling for Vanilla JavaScript
-
Section 31: More Practice Projects
-
Section 32: Interview and Algorithm Practice
-
Section 33: Error Objects (MDN Reference)
-
Section 34: TypedArrays and Binary Data
-
Section 35: Reflection and Metaprogramming (MDN Reference)
-
Section 36: More Global Functions (MDN Reference)
101: Modules: import and export
Wait, how do I actually move code into a separate file and use it elsewhere?
In the beginning, it's tempting to keep everything in one giant app.js file, but that becomes a nightmare to maintain. To split things up, you use export to mark what should be "public" and import to bring those pieces into another file.
Let's say we're building a shopping cart. I'd put my math logic in a file called cartUtils.js. If I want to use a function in my main logic, I just put the export keyword in front of it:
// cartUtils.js
export function calculateTax(price, taxRate) {
return price * taxRate;
}
export function formatCurrency(amount) {
return `$${amount.toFixed(2)}`;
}
Now, over in my main.js, I grab only what I need using curly braces. One detail I can't stress enough: when you're using native JavaScript modules in the browser, you must include the .js extension in your import path, or it'll just fail.
// main.js
import { calculateTax, formatCurrency } from './cartUtils.js';
const total = calculateTax(100, 0.07);
console.log(formatCurrency(total)); // "$7.00"
What's the deal with "default" exports vs "named" exports?
This is where most people get tripped up. Named exports (like the ones above) let you export multiple things from one file. Default exports are for when a file has one primary purpose—usually a single class or a main configuration object.
I generally prefer named exports because they make "Find All References" in your IDE work much better, but defaults are everywhere. Here is how they differ in syntax:
// User.js
export default class User {
constructor(name) {
this.name = name;
}
}
When you import a default, you don't use the curly braces. In fact, you can name it whatever you want during the import, though I highly recommend keeping the name consistent to avoid confusing your teammates.
// main.js
import User from './User.js';
const me = new User('Alex');
Can I just import everything from a file without listing every single function?
Yes, you can. If you have a utility file with twenty different functions, typing them all out in the import statement is a waste of time. You can use the * as syntax to bundle everything into a single namespace object.
Going back to our cartUtils.js example, instead of listing calculateTax and formatCurrency, do this:
// main.js
import * as CartHelper from './cartUtils.js';
const tax = CartHelper.calculateTax(50, 0.05);
const display = CartHelper.formatCurrency(tax);
I find this approach really helpful for keeping the global scope clean. Whenever I see CartHelper.something(), I know exactly which file that logic is living in without having to scroll to the top of the document.
📋 Practical Task
Refactoring the Order Processor
You have a single file orders.js that handles both data processing and string formatting. Your goal is to split this into two modules to make the code more maintainable.
Current Code:
// orders.js
function uppercaseName(name) {
return name.toUpperCase();
}
function calculateDiscount(price, percent) {
return price - (price * (percent / 100));
}
const customer = "Jane Doe";
const price = 100;
console.log(`${uppercaseName(customer)} paid ${calculateDiscount(price, 10)}`);
Your Task:
- Create a file named
formatter.js. Move theuppercaseNamefunction into it and export it as a named export. - Create a file named
calculator.js. Move thecalculateDiscountfunction into it and export it as the default export. - In your
orders.jsfile, import both functions and rewrite the finalconsole.logstatement so it still works exactly as before.
There are no comments for now.