Frontend Development 11 min read

What’s New in ES2021: Logical Assignment Operators, String Replacement, Promise.any, WeakRefs, and Numeric Separators

The article reviews the Stage‑4 proposals slated for ES2021, explaining logical assignment operators, efficient string replacement techniques, the new Promise.any method, WeakRef usage, and readable numeric separators, each illustrated with clear JavaScript code examples.

ByteFE
ByteFE
ByteFE
What’s New in ES2021: Logical Assignment Operators, String Replacement, Promise.any, WeakRefs, and Numeric Separators

ES2020 has just been released, and the TC39 committee is already planning the next set of features that will appear in ES2021. TC39 proposals progress through four stages (Stage 0 Strawperson, Stage 1 Proposal, Stage 2 Draft, Stage 3 Candidate, and Stage 4 Finished) before becoming part of the official ECMAScript specification.

Logical Assignment Operators

Logical assignment operators combine logical operators with assignment, allowing concise conditional assignments. ES2021 introduces three operators, each with two operands:

||=  // combines logical OR with ASSIGN
&&=  // combines logical AND with ASSIGN
??=  // combines NULLISH with ASSIGN

The ||= operator assigns the right‑hand value only when the left‑hand value is falsy (equivalent to a ||= b → a || (a = b) ).

let thirdPlace = 5;
let secondPlace = false;
let firstPlace = null;

thirdPlace ||= 3;
secondPlace ||= 2;
firstPlace ||= 1;

console.log(thirdPlace);   // "3"
console.log(secondPlace);  // "2"
console.log(firstPlace);   // "1"

The &&= operator works similarly but only when the left‑hand value is truthy ( a &&= b → a && (a = b) ).

let thirdPlace = 5;
let secondPlace = false;
let firstPlace = null;

thirdPlace &&= 3;
secondPlace &&= 2;
firstPlace &&= 1;

console.log(thirdPlace);   // "5"
console.log(secondPlace);  // "false"
console.log(firstPlace);   // "null"

The ??= operator assigns the right‑hand value only when the left‑hand value is null or undefined ( a ??= b → a ?? (a = b) ).

let thirdPlace = 5;
let secondPlace = false;
let firstPlace = null;

thirdPlace ??= 3;
secondPlace ??= 2;
firstPlace ??= 1;

console.log(thirdPlace);   // "5"
console.log(secondPlace);  // "false"
console.log(firstPlace);   // "1"

These operators are especially handy for initializing object properties with default values, reducing boilerplate such as person.firstName = person.firstName || 'Commander' to person.firstName ||= 'Commander' .

String Replacement

To replace all occurrences of a substring, a regular expression with the global flag is effective, or you can use a polyfill called replaceAllPolyfill() . Another approach is to split the string on the target substring and join the parts.

const winnersPhrase = 'This 111 is the 111 text 111 to gratulate 111 the winners 111 of the 111 race!';
const replaceAllPolyfill = (string, find, replace) => {
    return string.replace(new RegExp(find, 'g'), replace);
};
const correctPhrase = replaceAllPolyfill(winnersPhrase, ' 111', '');
console.log(correctPhrase); // This is the text to gratulate the winners of the race!

Using String.replaceAll() (available in future versions) simplifies this further by directly replacing every match.

const correctPhrase = winnersPhrase.replaceAll(' 111', '');
console.log(correctPhrase); // This is the text to gratulate the winners of the race!

Promise.any

ES2020 introduced Promise.allSettled() ; ES2021 adds Promise.any() , which resolves with the first fulfilled promise from an iterable, or rejects if all promises are rejected.

(async () => {
    const promises = [Promise.resolve(555), Promise.resolve(666), Promise.resolve(777)];
    try {
        const first = await Promise.any(promises);
        console.log(first); // 555
    } catch (e) { console.error(e); }
})();

(async () => {
    const mixed = [Promise.reject(555), Promise.reject(666), Promise.resolve(777)];
    try {
        const first = await Promise.any(mixed);
        console.log(first); // 777
    } catch (e) { console.error(e); }
})();

(async () => {
    const allRejected = [Promise.reject(1), Promise.reject(2), Promise.reject(5)];
    try {
        const first = await Promise.any(allRejected);
        console.log(first);
    } catch (e) {
        console.error(e); // All promises were rejected
    }
})();

WeakRefs

Since ES2015, WeakSet and WeakMap have provided weakly held collections. ES2021 introduces WeakRef , allowing explicit weak references to objects without preventing garbage collection. Use it cautiously, as its behavior depends on the engine’s GC implementation.

Numeric Separators

Numeric separators (underscores) improve readability of large numbers in decimal, binary, hexadecimal, and BigInt literals.

const goldstack1 = 785_00;
const gemstack = 1_000_000_000;
console.log(goldstack1); // 78500
console.log(gemstack);   // 1000000000
const goldStack = 0b1111_1111_1110_0101;
console.log(goldStack); // 65509
const goldStack = 0xFF_AC_C1;
console.log(goldStack); // 16755905
const bigNumber = 1_000_000_000_000_000n;
console.log(bigNumber); // 1000000000000000n

These separators do not affect the value or strict equality comparisons.

Conclusion

JavaScript continues to evolve, and the upcoming ES2021 release brings several powerful, concise features that simplify code and improve readability. When all Stage‑4 proposals are incorporated, ES2021 will represent a significant step forward for the language.

TC39: https://github.com/tc39/proposals

TC39 Stage 4: https://github.com/tc39/proposals/blob/master/finished-proposals.md

Original article: https://medium.com/front-end-weekly/dont-you-wish-an-es-fresh-like-es2021-e2b6ca33c983

JavaScriptES2021WeakRefLogical AssignmentNumeric SeparatorsPromise.any
ByteFE
Written by

ByteFE

Cutting‑edge tech, article sharing, and practical insights from the ByteDance frontend team.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.