Skip to content

Archive

JavaScript

47 articles
JavaScript 02 Sep 2026 6 min read

JavaScript Property Descriptors with Object.defineProperty

Most JavaScript properties are created with assignment or object literals. That is usually the right choice, but it hides several controls that every property carries: whether the property can be assigned, whether common enumeration APIs expose it, and whether its definition can later be changed. Property descriptors make those controls explicit. They are useful for library APIs, metadata, computed properties, compatibility layers, and cases where ordinary assignment exposes more behavior than intended.

JavaScript 02 Sep 2026 4 min read

Deep Cloning in JavaScript with structuredClone

Copying JavaScript objects looks simple until values contain nested arrays, dates, maps, sets, typed arrays, or circular references. A shallow spread copies only the first level, while the old JSON.stringify and JSON.parse pattern changes or rejects several legitimate JavaScript values. structuredClone provides a standard deep-cloning operation based on the structured clone algorithm used by browser messaging APIs. Shallow copies keep nested references A spread expression creates a new outer object:

JavaScript 02 Sep 2026 4 min read

Async Iteration and Backpressure with for await...of

JavaScript promises represent one future result. Many systems produce a sequence of future results instead: paginated records, stream chunks, queue messages, or events from an asynchronous source. Async iteration models that shape directly. An async iterable exposes values over time, and for await...of consumes them one at a time. A minimal async generator An async generator can yield values after asynchronous work: async function* pages() { for (let page = 1; page <= 3; page++) { const response = await fetch(`https://example.com/api/items?page=${page}`); if (!response.ok) { throw new Error(`HTTP ${response.status}`); } yield await response.json(); } } for await (const page of pages()) { console.log(page); } The consumer does not need to know how pagination is implemented. It only sees an asynchronous sequence.

JavaScript 01 Sep 2026 3 min read

Use structuredClone for Safe Deep Copying in JavaScript

Copying JavaScript values is easy until nested objects, dates, maps, sets, binary data, or circular references appear. The common JSON round trip works only for a limited subset of values and silently changes some data. The built-in structuredClone() API provides a defined deep-cloning algorithm for many JavaScript data types. Spread syntax is only a shallow copy Object spread copies the first level: const original = { profile: { name: "Ada" } }; const copy = { ...original }; copy.profile.name = "Grace"; console.log(original.profile.name); // "Grace" Both objects still reference the same nested profile. Spread syntax is useful when shallow copying is intentional, but it is not a general deep-copy mechanism.

JavaScript 01 Sep 2026 3 min read

Use JavaScript Import Maps for Browser Module Aliases

Native ES modules normally require browser-resolvable URLs such as ./math.js or /vendor/lib.js. Import maps add a controlled indirection layer so application code can use stable bare specifiers such as app/config without a bundler rewriting imports. Define a map before modules load <script type="importmap"> { "imports": { "app/": "/js/app/", "vendor-utils": "/vendor/utils-v3.js" } } </script> <script type="module" src="/js/main.js"></script> Then /js/main.js can use:

Web Development 01 Sep 2026 5 min read

Progressive Enhancement for Resilient Web Forms

A web form does not need JavaScript to submit data. That native capability is a useful reliability baseline. Progressive enhancement starts with semantic HTML and a server endpoint that can complete the operation, then adds JavaScript for faster feedback or richer interactions. If the enhancement fails, the core task still has a path to succeed. This approach is valuable even in highly interactive applications because JavaScript can fail for ordinary reasons: slow networks, stale cached chunks, browser extensions, runtime exceptions, or a partial deployment.

JavaScript 01 Sep 2026 5 min read

Choosing JavaScript Promise Combinators: all, allSettled, any, and race

JavaScript provides several Promise combinators that look similar but encode very different failure policies. Choosing between Promise.all, Promise.allSettled, Promise.any, and Promise.race is less about syntax and more about defining what “success” means for a group of asynchronous operations. The important question is not “which one runs in parallel?” Promises usually start when you create them. The combinator decides how to observe their outcomes. Promise.all: every result is required Use Promise.all when the operation is successful only if every input fulfills.

JavaScript 01 Sep 2026 5 min read

Cancel Fetch Requests and Prevent Stale UI Updates with AbortController

Fast user interfaces frequently start requests that become irrelevant before they finish. A search box may issue a request for ca, then cat, then catalog. If the oldest request finishes last, it can overwrite the newest results. AbortController gives JavaScript a standard way to cancel Fetch requests and other APIs that accept an AbortSignal. The basic cancellation pattern Create a controller and pass its signal to fetch: const controller = new AbortController(); const request = fetch('/api/profile', { signal: controller.signal, }); controller.abort(); Once aborted, the fetch promise rejects. Cancellation is therefore part of normal control flow and should be handled deliberately.

JavaScript Updated 07 Sep 2025 2 min read

Use Optional Chaining (`?.`) Safely in JavaScript

Optional chaining (?.) lets JavaScript stop a property-access chain when the value immediately before ?. is null or undefined. Instead of throwing, the expression evaluates to undefined. Nested Properties const user = { profile: { name: 'Alice', address: { city: 'Wonderland' }, }, }; const city = user.profile?.address?.city; const postalCode = user.profile?.address?.postalCode; postalCode is undefined rather than causing an error.

JavaScript Updated 02 Sep 2025 1 min read

Use `Promise.any()` for the First Successful Result

Promise.any() fulfills as soon as one input promise fulfills. Rejections are ignored until either a promise succeeds or every input promise has rejected. const first = Promise.reject(new Error('first failed')); const second = new Promise((resolve) => setTimeout(resolve, 100, 'second succeeded')); const third = new Promise((resolve) => setTimeout(resolve, 200, 'third succeeded')); console.log(await Promise.any([first, second, third])); // second succeeded When Everything Fails If every promise rejects, Promise.any() rejects with an AggregateError:

JavaScript Updated 02 Sep 2025 1 min read

Replace Every Match with JavaScript `String.replaceAll()`

String.prototype.replaceAll() replaces every occurrence of a substring or every match of a global regular expression and returns a new string. Replace a Literal Substring const text = 'Hello World! Welcome to the World of JavaScript.'; const result = text.replaceAll('World', 'Universe'); Use a Regular Expression When searchValue is a RegExp, it must use the g flag:

JavaScript Updated 02 Sep 2025 2 min read

Private Fields and Methods in JavaScript Classes

JavaScript classes support truly private fields and methods using names that begin with #. They can be accessed only from code inside the class body that declares them. Private Fields class Person { #name; constructor(name) { this.#name = name; } getName() { return this.#name; } } Trying to access person.#name outside the class is a syntax error.

JavaScript Updated 02 Sep 2025 1 min read

JavaScript RegExp `d` Flag: Get Match Indices

The JavaScript regular-expression d flag enables match indices. It does not collect repeated captures; instead, it adds an indices property that tells you the start and end offsets of the overall match and each capturing group. Basic Example const regex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/d; const match = regex.exec('Date: 2024-08-30'); console.log(match[0]); // 2024-08-30 console.log(match.indices[0]); // [6, 16] console.log(match.indices.groups.year); // [6, 10] console.log(match.indices.groups.month); // [11, 13] console.log(match.indices.groups.day); // [14, 16] The end index is exclusive, matching the behavior of String.prototype.slice().

JavaScript Updated 07 Sep 2025 1 min read

JavaScript Numeric Separators (`_`)

JavaScript numeric separators let you place underscores inside numeric literals to improve readability. They do not change the numeric value. const million = 1_000_000; console.log(million); // 1000000 Decimal Fractions const pi = 3.141_592_653; Binary, Octal, and Hexadecimal const binary = 0b1010_1011; const octal = 0o123_456; const hex = 0xFF_FF_FF; Separators can also be used in BigInt literals:

JavaScript Updated 07 Sep 2025 1 min read

JavaScript Nullish Coalescing Operator (`??`)

The nullish coalescing operator, ??, provides a fallback only when the left-hand value is null or undefined. const username = null; const name = username ?? 'Guest'; console.log(name); // Guest ?? vs. || || falls back for every falsy value. ?? preserves valid falsy data such as 0, false, and '':

JavaScript Updated 07 Sep 2025 2 min read

JavaScript BigInt: Handling Large Integers

JavaScript Number can represent integers exactly only up to Number.MAX_SAFE_INTEGER (2^53 - 1). When you need larger integer values without losing precision, use BigInt. Create a BigInt const a = 123456789012345678901234567890n; const b = BigInt('123456789012345678901234567890'); The n suffix creates a BigInt literal. BigInt() is useful when converting a string or an integer-valued Number.

JavaScript Updated 02 Sep 2025 1 min read

JavaScript `||=`: Logical OR Assignment

The logical OR assignment operator, ||=, assigns a new value only when the current left-hand value is falsy. let name = ''; name ||= 'Guest'; console.log(name); // 'Guest' Falsy values include false, 0, -0, 0n, '', null, undefined, and NaN.

JavaScript Updated 02 Sep 2025 1 min read

JavaScript `&&=`: Logical AND Assignment

The logical AND assignment operator, &&=, assigns a new value to its left-hand operand only when the current value is truthy. Basic Syntax variable &&= newValue; Conceptually, this is similar to:

JavaScript Updated 07 Sep 2025 1 min read

JavaScript `??=`: Nullish Coalescing Assignment

The nullish coalescing assignment operator, ??=, assigns a value only when the current left-hand value is null or undefined. let name = null; name ??= 'Guest'; console.log(name); // Guest Function Defaults function greet(user) { user ??= 'Stranger'; console.log(`Hello, ${user}!`); } A default parameter may be even clearer when only undefined needs a fallback:

JavaScript Updated 02 Sep 2025 1 min read

Handle Multiple Promises with `Promise.allSettled()`

Promise.allSettled() waits until every input promise has either fulfilled or rejected, then returns the outcome of each operation. Unlike Promise.all(), one rejection does not stop you from receiving the other results. const tasks = [ Promise.resolve('first result'), Promise.reject(new Error('second failed')), Promise.resolve('third result'), ]; const results = await Promise.allSettled(tasks); for (const result of results) { if (result.status === 'fulfilled') { console.log('Value:', result.value); } else { console.error('Error:', result.reason); } } Each result has one of these shapes:

JavaScript Updated 02 Sep 2025 1 min read

Get Every RegExp Match with `String.matchAll()`

String.prototype.matchAll() returns an iterator containing every match of a global regular expression, including capturing groups and match indexes. const text = 'Order #123, Order #456, Order #789'; const regex = /Order #(\d+)/g; for (const match of text.matchAll(regex)) { console.log(match[0], match[1], match.index); } Named Capturing Groups const text = 'John: 123, Jane: 456'; const regex = /(?<name>\w+): (?<number>\d+)/g; for (const match of text.matchAll(regex)) { console.log(match.groups.name, match.groups.number); } Convert the Iterator to an Array const matches = [...'cat bat mat'.matchAll(/\b(\w+)at\b/g)]; This is convenient when you need map, filter, or other array operations, but iterating directly avoids storing all matches at once.

JavaScript Updated 02 Sep 2025 1 min read

Access JavaScript Array Elements with `at()`

Array.prototype.at() returns the element at a given integer index. Its main advantage over bracket notation is support for negative indexes. Positive Indexes const fruits = ['apple', 'banana', 'cherry']; console.log(fruits.at(0)); // 'apple' console.log(fruits.at(1)); // 'banana' Negative Indexes console.log(fruits.at(-1)); // 'cherry' console.log(fruits.at(-2)); // 'banana' Without at(), the traditional equivalent for the last element is:

JavaScript Updated 07 Sep 2025 1 min read

Update JavaScript Arrays Immutably with `with()`

Array.prototype.with() returns a copy of an array with one element replaced. The source array is left unchanged. const colors = ['red', 'blue', 'green', 'yellow']; const updated = colors.with(1, 'purple'); console.log(updated); // ['red', 'purple', 'green', 'yellow'] console.log(colors); // ['red', 'blue', 'green', 'yellow'] Negative Indexes Like at(), with() accepts negative indexes:

JavaScript Updated 02 Sep 2025 2 min read

Understanding Variable Scope in JavaScript

Variable scope determines where a name can be accessed. JavaScript uses lexical scope, with important differences between var, let, and const. Global Scope A binding declared at the top level can be visible throughout its module or script: const globalValue = 'global'; function showValue() { console.log(globalValue); } In modern ES modules, top-level declarations do not automatically become properties of window.