-
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)
105: Array and Object New Methods by Version
I've seen this happen to a lot of talented developers: you're browsing MDN, you find a beautifully concise method like .at() or Object.fromEntries(), you drop it into your code, and it works perfectly on your machine. Then, you deploy it, and suddenly your error logs are screaming with TypeError: ... is not a function because a user is on a slightly older browser or your production server is running an older LTS version of Node.js.
The "If it's in the docs, it's universal" trap
The misconception here is that "JavaScript" is a static entity. Many learners assume that if a method is listed in the official documentation, it's a core part of the language that has always been there. In reality, JavaScript is an evolving specification (ECMAScript) that adds new capabilities every single year.
// This looks clean and modern
const users = [{ name: 'Alice' }, { name: 'Bob' }];
const lastUser = users.at(-1);
// But if this runs in Node.js 14 or Chrome 89,
// it crashes. .at() wasn't added until ES2022.
When you see a crash like this, it's not because you wrote "wrong" code; it's because you're using a tool that hasn't been invented yet in that specific environment. I used to just blindly install polyfills to fix this, but the better approach is to actually understand the timeline of the language so you can make intentional choices about compatibility.
Matching the method to the version
You don't need to memorize the exact date every method was released, but you should recognize the "eras." For most of us, the biggest divide is between ES5 (the old world) and ES6/ES2015 (the modern world). However, the last few years have introduced some high-utility methods for Arrays and Objects that are worth tracking.
Here is how I categorize the recent heavy-hitters:
- The "Modern Foundation" (ES2017-2019): Methods like
Object.entries()andObject.values()changed how we iterate over objects. ThenObject.fromEntries()(ES2019) gave us the inverse—turning an array of pairs back into an object. These are generally safe in almost every environment now. - The "Convenience Layer" (ES2020-2022): This is where
Array.prototype.at()andString.prototype.replaceAll()live. They don't add "new" power (you could always uselength - 1), but they make the code much more readable. - The "Immutability Wave" (ES2023): This is the most important recent shift. For years, methods like
.sort()and.reverse()were dangerous because they mutated the original array. Now we have.toSorted(),.toReversed(), and.toSpliced(). These return a copy, leaving the original intact.
const scores = [10, 5, 8];
// The old way: scores is now [5, 8, 10] (Mutated!)
// scores.sort();
// The ES2023 way: scores remains [10, 5, 8]
const sortedScores = scores.toSorted();
I personally love the toSorted family because it eliminates a whole class of bugs where you accidentally change a data source that other parts of your app are relying on. Just keep in mind: if you're targeting older browsers, you'll need a transpiler like Babel to turn these new methods into something older engines can understand.
📋 Practical Task
Refactoring a Legacy Inventory Pipeline to Non-Mutating Methods
You have been handed a legacy function that processes a product inventory. The current implementation uses .sort() and .reverse(), which are mutating the original inventory array and causing bugs in the UI components that display the original list.
Your Task: Refactor the processInventory function to use the ES2023 non-mutating alternatives (.toSorted() and .toReversed()) so that the original inventory array remains unchanged.
const inventory = [
{ name: 'Laptop', price: 1200 },
{ name: 'Mouse', price: 25 },
{ name: 'Keyboard', price: 75 },
{ name: 'Monitor', price: 300 }
];
function processInventory(items) {
// TODO: Refactor this to be non-mutating
// Currently, this changes the 'inventory' array globally
const result = items.sort((a, b) => a.price - b.price);
return result.reverse();
}
const cheapestToExpensive = processInventory(inventory);
console.log('Processed:', cheapestToExpensive);
// Should be: Mouse, Keyboard, Monitor, Laptop
console.log('Original Inventory:', inventory);
// SHOULD remain in the original order: Laptop, Mouse, Keyboard, Monitor
// If it's sorted, you haven't fixed the bug!
There are no comments for now.