JavaScript ES13 (2022)

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:

  1. ES13 overview
  2. Feature-by-feature explanations
  3. 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) in Error 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

FeatureDescriptionExample
Class fieldsDefine class properties without constructorname = "Guest"
Private fieldsEncapsulate data in class#password = "1234"
Static blocksRun setup code in static contextstatic { ... }
at() methodIndex from end using negative valuesarr.at(-1)
Top-level awaitUse await in modulesawait fetch()
Object.hasOwn()Check direct property of objectObject.hasOwn(obj, "prop")
Error causeInclude cause in error objectnew Error("msg", { cause })
RegExp match indicesGet 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.