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)
218: Linting with ESLint
A few years ago, I was reviewing a pull request for a junior dev who had written a complex conditional to handle user permissions. Everything looked fine at a glance, but when we hit production, the app started letting guest users access the admin dashboard. It took me nearly two hours of staring at the code to realize they'd written if (user.role = 'admin') instead of if (user.role === 'admin'). They weren't checking if the user was an admin; they were accidentally assigning the admin role to every single person who hit that line of code.
It was a tiny typo, but a catastrophic one. The worst part? A linter would have flagged that in milliseconds. That's why I don't view ESLint as some annoying "style police" tool—I view it as a safety net that catches the stupid mistakes we all make when we're tired or rushing.
Setting Up Your Project Guardrails
At its core, ESLint is a static analysis tool. It reads your code without actually running it and looks for patterns that are known to be problematic. To get started, you don't want to manually write every single rule from scratch—that would be a nightmare. Instead, we usually initialize a config file using npm init @eslint/config.
This process generates a configuration file (usually .eslintrc.json or eslint.config.js in newer versions). This file is essentially the "law of the land" for your project. If you're working on a team, this ensures that whether I'm writing the code or you are, it looks and behaves consistently. I personally prefer using a shared config like eslint-config-airbnb-base or the recommended defaults, because arguing over whether to use single or double quotes in a meeting is a waste of everyone's time.
Distinguishing Style from Logic
When you start digging into the rules, you'll notice they generally fall into two buckets: stylistic preferences and logic errors. Stylistic rules are things like indent or quotes. While these make the code easier to read, they aren't going to crash your server. Logic rules, however, are critical. Rules like no-undef (which stops you from using a variable that hasn't been declared) or no-unreachable (which flags code after a return statement) save you from hours of debugging.
// ESLint would flag these immediately:
const x = 10;
if (x == 10) { // Warning: eqeqeq (use === instead)
console.log("Match");
}
const user = { name: "Dev" };
console.log(user.namme); // Error: no-undef (namme is not defined)
I always tell my mentees: don't fight the linter. If it's complaining, it's usually because you're doing something that could potentially bite you later. If you absolutely must bypass a rule for a very specific edge case, you can use a comment like /* eslint-disable-line */, but use that sparingly. If your code is littered with disable comments, you're not using a linter—you're just silencing a warning.
Automating the Cleanup
The real magic happens when you stop running the linter via the command line and integrate it directly into your IDE. When you see those red squiggly lines under your code in real-time, you fix the mistake before you even finish the thought.
Furthermore, most stylistic issues can be handled automatically. Running eslint --fix will go through your files and automatically swap those double quotes for single ones or add missing semicolons. I usually pair ESLint with Prettier for the formatting side of things, letting Prettier handle the "look" and ESLint handle the "correctness." It's a powerful combination that lets you focus on solving the actual problem rather than worrying about where the curly braces go.
📋 Practical Task
Fixing the Buggy Order Processor
You've been handed a piece of legacy code for an e-commerce order processor. It is riddled with "smells" and potential bugs that a linter would normally catch. Your task is to manually "lint" this code by fixing the following issues:
- Change all loose equality checks (
==) to strict equality (===). - Find and remove the unused variable that is declared but never used.
- Fix the accidental assignment inside the
ifstatement (similar to the anecdote in the lesson). - Replace the outdated
vardeclarations withletorconst.
function processOrder(order) {
var status = 'pending';
var internalTrackingId = 'TRK-12345'; // This is never used
var discountApplied = false;
if (order.total == 0) {
return 'Free Order';
}
// BUG: This is assigning 'shipped' to order.status instead of comparing it
if (order.status = 'shipped') {
return 'Order already sent';
}
if (discountApplied == false) {
console.log("No discount found");
}
return 'Order processed successfully';
}
There are no comments for now.