JavaScript ES13, or ECMAScript 2022, introduced several enhancements focused on making code cleaner, safer, and easier to write. While it didn’t bring massive changes like ES6, it provided quality-of-life improvements across many areas — from working with classes and arrays to better handling asynchronous code.
This tutorial includes:
- ES13 overview
- Feature-by-feature explanations
- A real-world code model using ES13
🔍 What’s New in ES13?
Key features introduced in ECMAScript 2022:
- Class Fields and Private Methods
- Static class initialization blocks
at()
method for indexing- Top-level
await
Object.hasOwn()
(standardized)- Error cause (
.cause
) inError
objects - RegExp Match Indices (
/d
flag)
🔐 1. Class Fields and Private Methods
You can now define properties directly inside a class and use #
to create private fields and methods.
javascriptCopyEditclass User {
name = "Guest";
#password = "secret"; // private
getName() {
return this.name;
}
#getPassword() {
return this.#password;
}
}
This simplifies class definitions by avoiding constructor boilerplate and improves encapsulation.
⚡ 2. Static Initialization Blocks
Use static blocks to initialize class-level values dynamically.
javascriptCopyEditclass Config {
static settings;
static {
this.settings = { theme: "dark", version: 1.0 };
}
}
console.log(Config.settings); // { theme: 'dark', version: 1.0 }
Useful for computing static values at runtime.
🔢 3. at()
Method for Arrays & Strings
The new .at()
method lets you access elements by index, including negative indexes.
javascriptCopyEditconst arr = [10, 20, 30];
console.log(arr.at(-1)); // 30 (last element)
const str = "Hello";
console.log(str.at(-2)); // 'l'
⏳ 4. Top-Level await
You can now use await
outside of async functions — directly at the module’s top level.
javascriptCopyEditconst response = await fetch("https://api.example.com");
const data = await response.json();
console.log(data);
This makes async workflows easier in modern JavaScript modules (.mjs
files or using "type": "module"
).
🧼 5. Object.hasOwn()
(Standardized)
This method was introduced in ES12 but standardized in ES13. It’s a safer and cleaner way to check if an object has a direct property.
javascriptCopyEditconst user = { name: "Alice" };
console.log(Object.hasOwn(user, "name")); // true
🧠 6. Error Cause
Now you can provide an underlying cause when throwing an error. This improves debugging.
javascriptCopyEdittry {
throw new Error("Something went wrong", { cause: "Invalid input" });
} catch (e) {
console.log(e.message); // Something went wrong
console.log(e.cause); // Invalid input
}
🔍 7. RegExp Match Indices (/d
flag)
The /d
flag allows you to get start and end positions of matches.
javascriptCopyEditconst regex = /(hello)/d;
const result = regex.exec("hello world");
console.log(result.indices); // [[0, 5], [0, 5]]
This is useful for syntax highlighting or advanced parsing.
🛠 Code Model: User Info Processor
🎯 Goal:
- Create a
User
class with private data - Access the last user activity using
.at()
- Handle fetch errors with
.cause
- Use top-level
await
to fetch user data
✅ ES13 Code Model:
javascriptCopyEditclass User {
name;
#email;
constructor(name, email) {
this.name = name;
this.#email = email;
}
getInfo() {
return `${this.name} (${this.#email})`;
}
static history = [];
static {
// Initialize user activity history
this.history = ["login", "update-profile", "logout"];
}
}
try {
const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
if (!response.ok) {
throw new Error("Failed to fetch user", { cause: response.status });
}
const data = await response.json();
const user = new User(data.name, data.email);
console.log("User Info:", user.getInfo());
console.log("Last Activity:", User.history.at(-1));
} catch (err) {
console.log("Error:", err.message);
console.log("Cause:", err.cause);
}
🖥 Output:
lessCopyEditUser Info: Leanne Graham (Sincere@april.biz)
Last Activity: logout
🧠 Summary Table
Feature | Description | Example |
---|---|---|
Class fields | Define class properties without constructor | name = "Guest" |
Private fields | Encapsulate data in class | #password = "1234" |
Static blocks | Run setup code in static context | static { ... } |
at() method | Index from end using negative values | arr.at(-1) |
Top-level await | Use await in modules | await fetch() |
Object.hasOwn() | Check direct property of object | Object.hasOwn(obj, "prop") |
Error cause | Include cause in error object | new Error("msg", { cause }) |
RegExp match indices | Get match positions with /d flag | /pattern/d |
✅ Conclusion
JavaScript ES13 (2022) delivered powerful tools for improving object-oriented code, handling asynchronous logic, and working with arrays and strings. These features reduce boilerplate, improve readability, and make modern JavaScript cleaner and more intuitive.
If you work with classes, fetch data, or write modern web apps, ES13 tools help make your code production-ready and future-proof.