JavaScript ES12 (2021)

ECMAScript 2021, or JavaScript ES12, introduced a set of small but powerful features that improve developer experience, especially in areas like string manipulation, object handling, Promise debugging, and logical operations.

In this tutorial, you’ll learn:

  1. Overview of ES12
  2. Key features with examples
  3. A code model project using ES12 features

🔍 What’s New in ES12 (2021)?

The ES12 update includes:

  • Logical Assignment Operators (||=, &&=, ??=)
  • Numeric Separators
  • String.prototype.replaceAll()
  • Promise any()
  • WeakRef and FinalizationRegistry
  • Object.hasOwn()

Let’s break them down.


1. ✅ Logical Assignment Operators (||=, &&=, ??=)

These are shorthand ways of combining logic and assignment.

🧪 Examples:

javascriptCopyEditlet name = null;
name ||= "Guest";       // name = "Guest"

let count = 5;
count &&= 10;           // count = 10

let title = undefined;
title ??= "Untitled";   // title = "Untitled"

This simplifies conditionally setting variables.


2. 🔢 Numeric Separators (_)

You can use underscores (_) to make large numbers more readable.

javascriptCopyEditconst billion = 1_000_000_000;
console.log(billion); // 1000000000

This does not affect the value—just the readability.


3. 🔁 String.prototype.replaceAll()

Replaces all instances of a substring without needing regex with global flag.

javascriptCopyEditconst text = "apple, banana, apple";
const updated = text.replaceAll("apple", "orange");
console.log(updated); // "orange, banana, orange"

This is more intuitive than using text.replace(/apple/g, 'orange').


4. 🔂 Promise.any()

Returns the first fulfilled promise. If all reject, it returns an AggregateError.

javascriptCopyEditconst p1 = Promise.reject("Fail 1");
const p2 = Promise.resolve("Success");
const p3 = Promise.reject("Fail 2");

Promise.any([p1, p2, p3]).then(result => {
  console.log(result); // "Success"
});

Perfect when you want any successful result from multiple sources.


5. 🧼 Object.hasOwn() (Better than hasOwnProperty())

Checks if an object has a direct property of its own.

javascriptCopyEditconst user = { name: "Alice" };
console.log(Object.hasOwn(user, "name")); // true

It’s more reliable than using hasOwnProperty because it works even if the object doesn’t inherit from Object.prototype.


6. 🧠 WeakRef and FinalizationRegistry (Advanced)

These deal with memory management and garbage collection.

javascriptCopyEditlet obj = { name: "data" };
let ref = new WeakRef(obj);

// Later: you can dereference the weak reference
console.log(ref.deref()); // { name: "data" }

Useful for building caches or observers, but not often needed in everyday projects.


🛠 Code Model: Post Processor Tool

🎯 Objective:

  • Set default metadata with logical assignment
  • Replace all keywords in post content
  • Check if post has certain data
  • Format large view counts
  • Resolve any available translations using Promise.any()

✅ ES12 Code Example:

javascriptCopyEdit// Initial post object
let post = {
  title: undefined,
  content: "Learn JS. JS is fun!",
  views: 25_000,
  tags: null,
};

// Logical assignment to set defaults
post.title ??= "Untitled Post";
post.tags ||= ["javascript", "tutorial"];

// Replace all mentions of "JS" with "JavaScript"
post.content = post.content.replaceAll("JS", "JavaScript");

// Display view count using numeric separator
console.log(`Views: ${post.views}`);

// Check if property exists
if (Object.hasOwn(post, "title")) {
  console.log("Title exists:", post.title);
}

// Simulate translations loading
const en = Promise.reject("No English");
const es = Promise.resolve("Artículo en Español");
const fr = Promise.reject("Aucun Français");

Promise.any([en, es, fr])
  .then(translation => {
    console.log("Translation loaded:", translation);
  })
  .catch(error => {
    console.log("No translations available:", error);
  });

🖥 Output:

yamlCopyEditViews: 25000
Title exists: Untitled Post
Translation loaded: Artículo en Español

This project uses:

  • ??=, ||= for safe default values
  • replaceAll() for content replacement
  • Object.hasOwn() for safety checking
  • Promise.any() for loading available translations
  • 25_000 for improved readability with numeric separators

🧠 Summary Table

FeatureDescriptionExample
??=, `=, &&=`
Numeric separatorsMakes large numbers readable1_000_000
replaceAll()Replace all substrings in a string"a a".replaceAll("a", "b")
Promise.any()Returns first fulfilled PromisePromise.any([...])
Object.hasOwn()Checks direct object propertyObject.hasOwn(obj, 'key')
WeakRefWeak reference to an objectnew WeakRef(obj)

✅ Conclusion

JavaScript ES12 (2021) focused on ergonomics — making common tasks easier, safer, and more readable. Whether you’re assigning default values, working with promises, or processing strings, these features simplify your code and reduce boilerplate.

Even if you’re a beginner, features like ??=, replaceAll(), and Promise.any() are quick wins for writing cleaner, modern JavaScript.