---
title: "JavaScript"
lang: "en"
author: "Mohammad Abu Mattar"
canonical: https://mkabumattar.com/javascript
---

[Home](/)›[Cheatsheets](/cheatsheets)

Cheatsheets

# JavaScript

JavaScript is a high-level programming language that powers the web. It supports object-oriented, functional, and event-driven programming styles.

8 Categories21 Sections41 ExamplesPublished: 15 Mar 2023Updated: 27 Feb 2025

JavaScriptES6Web DevelopmentFrontendNode.jsProgramming

[Markdown for AI(opens in a new tab)](/javascript/index.md "Open the plain-Markdown version of this page, for pasting into an AI tool")

Series

[Programming Languages](/series/programming-languages)3/4

[PreviousPython](/cheatsheets/python)[NextGo](/cheatsheets/go)

All posts in this series (4)

Cheatsheets4

1.  [Dart](/cheatsheets/dart)
2.  [Python](/cheatsheets/python)
3.  [JavaScriptYou are here](/cheatsheets/javascript)
4.  [Go](/cheatsheets/go)

JavaScript is a high-level programming language that powers the web. It supports object-oriented, functional, and event-driven programming styles.

The sections below cover JavaScript syntax and methods, including ES6+ features, async patterns, classes, and modules.

[Getting Started](#category-getting-started)

-   [Variables](#section-variables)
-   [Data Types](#section-data-types)
-   [Template Literals](#section-template-literals)
-   [Operators](#section-operators)

[Functions](#category-functions)

-   [Arrow Functions](#section-arrow-functions)
-   [Default Parameters](#section-default-parameters)
-   [Closures](#section-closures)

[Objects and Arrays](#category-objects-and-arrays)

-   [Destructuring](#section-destructuring)
-   [Spread and Rest](#section-spread-and-rest)
-   [Array Methods](#section-array-methods)
-   [Object Methods](#section-object-methods)

[Async JavaScript](#category-async-javascript)

-   [Promises](#section-promises)
-   [Async/Await](#section-async-await)

[Classes and Modules](#category-classes-and-modules)

-   [Classes](#section-classes)
-   [Modules](#section-modules)

[Error Handling](#category-error-handling)

-   [Try/Catch](#section-try-catch)

[Iterators and Generators](#category-iterators-and-generators)

-   [Iterators](#section-iterators)
-   [Generators](#section-generators)

[Modern Features](#category-modern-features)

-   [Map and Set](#section-map-and-set)
-   [Proxy and Reflect](#section-proxy-and-reflect)
-   [Miscellaneous Modern Features](#section-misc-modern)

No commands found

Try adjusting your search term

## Getting Started

Fundamental JavaScript concepts including variables, data types, and basic syntax.

### Variables

Declaring and using variables with var, let, and const.

#### Accessibility

Ensure variable names are descriptive for code readability.

#### Best Practices

-   Use const by default, let when you need to reassign.
-   Never use var in modern code.
-   Declare variables at the top of their scope for clarity.

#### Common Errors

-   **Using const and then trying to reassign:** Use let if the variable needs to change.
-   **Accessing let/const before declaration (temporal dead zone):** Always declare variables before using them.

#### Keywords

varletconstvariabledeclarationscopehoisting

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let)

#### Variable declarations

let and const are block-scoped. var is function-scoped and hoisted. const prevents reassignment but does not make objects immutable.

Code

```
1var oldWay = 'function scoped';2let mutable = 'can be reassigned';3const immutable = 'cannot be reassigned';4
5let x = 1;6x = 2; // OK7
8const y = 1;9// y = 2; // TypeError: Assignment to constant variable
```

Execution

Terminal window

```
node variables.js
```

-   Prefer const by default, use let only when reassignment is needed.
-   Avoid var in modern JavaScript.

#### Block scoping

var leaks out of blocks, while let and const are confined to the block where they are declared.

Code

```
1if (true) {2  var a = 1;3  let b = 2;4  const c = 3;5}6console.log(a); // 17// console.log(b); // ReferenceError8// console.log(c); // ReferenceError
```

Execution

Terminal window

```
node scope.js
```

Output

```
11
```

-   Block scoping prevents variable leaks and accidental overwrites.
-   This is one of the main reasons to prefer let/const over var.

### Data Types

JavaScript primitive and reference types.

#### Accessibility

Use typeof checks to make type handling explicit.

#### Best Practices

-   Use strict equality (===) to avoid implicit type coercion.
-   Use Array.isArray() to check for arrays instead of typeof.
-   Use Number.isNaN() instead of global isNaN().

#### Common Errors

-   **Using typeof to check for null returns "object":** Use value === null for explicit null checks.
-   **Confusing undefined and null:** Use undefined for uninitialized, null for intentional absence of value.

#### Keywords

stringnumberbooleanundefinedsymbolbigintobjecttypeof

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures)

#### Primitive types

JavaScript has 7 primitive types. typeof null returning "object" is a well-known historical bug.

Code

```
1const str = 'hello';          // string2const num = 42;               // number3const float = 3.14;           // number4const bool = true;            // boolean5const nothing = null;         // object (historical bug)6const undef = undefined;      // undefined7const sym = Symbol('id');     // symbol8const big = 9007199254740991n; // bigint9
10console.log(typeof str);      // "string"11console.log(typeof num);      // "number"12console.log(typeof nothing);  // "object"
```

Execution

Terminal window

```
node types.js
```

Output

```
1string2number3object
```

-   Use === instead of == to avoid type coercion surprises.
-   BigInt is for integers larger than Number.MAX\_SAFE\_INTEGER.

#### Type checking

typeof works for most types but returns "object" for null and arrays. Use Array.isArray() for arrays.

Code

```
1typeof 'hello'      // "string"2typeof 42           // "number"3typeof true         // "boolean"4typeof undefined    // "undefined"5typeof null         // "object" (bug)6typeof {}           // "object"7typeof []           // "object"8Array.isArray([])   // true9typeof function(){} // "function"
```

-   Use instanceof for checking class instances.
-   null check: value === null.

### Template Literals

String interpolation and multiline strings using backticks.

#### Accessibility

Template literals improve code readability with embedded expressions.

#### Best Practices

-   Use template literals instead of string concatenation.
-   Keep expressions inside ${} simple; extract complex logic to variables.

#### Common Errors

-   **Using single/double quotes instead of backticks for interpolation:** Template literals require backticks (\`), not single (') or double ("") quotes.
-   **Forgetting ${} around expressions:** Wrap expressions in ${} inside template literals.

#### Keywords

templatebacktickinterpolationstringmultilinetagged

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals)

#### String interpolation

Template literals use backticks and ${} for embedding expressions directly in strings.

Code

```
1const name = 'World';2const greeting = `Hello, ${name}!`;3console.log(greeting);4
5const a = 10, b = 20;6console.log(`Sum: ${a + b}`);7console.log(`Type: ${typeof name}`);
```

Execution

Terminal window

```
node template.js
```

Output

```
1Hello, World!2Sum: 303Type: string
```

-   Any valid JavaScript expression can go inside ${}.
-   Template literals preserve whitespace and newlines.

#### Multiline strings and tagged templates

Tagged templates allow custom processing of template literals through a function prefix.

Code

```
1const multiline = `2  This is a3  multiline string4`;5
6function highlight(strings, ...values) {7  return strings.reduce((result, str, i) =>8    `${result}${str}<b>${values[i] || ''}</b>`, '');9}10
11const name = 'world';12console.log(highlight`Hello ${name}!`);
```

Execution

Terminal window

```
node tagged.js
```

Output

```
1Hello <b>world</b>!<b></b>
```

-   Tagged templates are used in libraries like styled-components and GraphQL.
-   The tag function receives an array of string parts and interpolated values.

### Operators

Comparison, logical, nullish coalescing, and optional chaining operators.

#### Accessibility

Use explicit operators for clear logic flow.

#### Best Practices

-   Use ?? instead of || when 0 or empty string are valid values.
-   Use optional chaining to safely access deeply nested objects.
-   Prefer strict equality (===) over loose equality (==).

#### Common Errors

-   **Using || for defaults when 0 or "" are valid values:** Use ?? (nullish coalescing) which only triggers for null/undefined.
-   **Not using optional chaining on potentially null objects:** Use obj?.prop to avoid "Cannot read property of null/undefined" errors.

#### Keywords

operatorcomparisonequalityternarynullishoptional chainingspread

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators)

#### Comparison and logical operators

?? only checks null/undefined, unlike || which also catches 0, "", and false.

Code

```
1// Equality21 == '1'        // true (type coercion)31 === '1'       // false (strict)41 != '1'        // false51 !== '1'       // true6
7// Logical8true && 'yes'   // "yes"9false || 'fallback' // "fallback"10null ?? 'default'   // "default" (nullish coalescing)11
12// Ternary13const age = 20;14const status = age >= 18 ? 'adult' : 'minor';
```

-   Always use === and !== to avoid type coercion bugs.
-   ?? is safer than || when 0 or empty string are valid values.

#### Optional chaining and nullish assignment

Optional chaining (?.) safely accesses nested properties without throwing if intermediate values are null/undefined.

Code

```
1const user = {2  name: 'Alice',3  address: { city: 'NYC' }4};5
6// Optional chaining7console.log(user?.address?.city);    // "NYC"8console.log(user?.phone?.number);    // undefined9
10// Optional chaining with methods11console.log(user.toString?.());      // "[object Object]"12console.log(user.nonExistent?.());   // undefined13
14// Nullish assignment15let a = null;16a ??= 'default';17console.log(a); // "default"18
19let b = 0;20b ??= 42;21console.log(b); // 0 (not null/undefined)
```

Execution

Terminal window

```
node optional.js
```

Output

```
1NYC2undefined3[object Object]4undefined5default60
```

-   ?.() for optional method calls, ?.\[\] for optional bracket access.
-   Combine with ?? for safe default values.

## Functions

Function declarations, expressions, arrow functions, and advanced patterns.

### Arrow Functions

Concise function syntax introduced in ES6.

#### Accessibility

Arrow functions improve code conciseness and readability.

#### Best Practices

-   Use arrow functions for callbacks and short functions.
-   Use traditional function declarations for methods that need their own this.
-   Wrap object literal returns in parentheses.

#### Common Errors

-   **Using arrow functions as object methods and losing this context:** Use regular function syntax for object methods that need this.
-   **Forgetting parentheses when returning object literals:** Use () => ({ key: value }) to return objects.

#### Keywords

arrowfunctionlambdafat arrowimplicit returnthis

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions)

#### Arrow function syntax

Arrow functions provide concise syntax. Single expressions are implicitly returned. Multi-line bodies need explicit return.

Code

```
1// Basic arrow function2const add = (a, b) => a + b;3
4// Single parameter (no parens needed)5const double = x => x * 2;6
7// No parameters8const greet = () => 'Hello!';9
10// Multi-line body (needs braces and return)11const sum = (a, b) => {12  const result = a + b;13  return result;14};15
16console.log(add(2, 3));    // 517console.log(double(4));    // 818console.log(greet());      // "Hello!"
```

Execution

Terminal window

```
node arrow.js
```

Output

```
15283Hello!
```

-   Arrow functions do not have their own this - they inherit it from the enclosing scope.
-   Cannot be used as constructors (no new keyword).

#### Returning objects

To return an object literal from an arrow function, wrap it in parentheses to avoid ambiguity with block syntax.

Code

```
1// Wrap object literal in parentheses2const makeUser = (name, age) => ({ name, age });3
4console.log(makeUser('Alice', 30));5// { name: 'Alice', age: 30 }6
7// Common in array methods8const names = ['Alice', 'Bob'];9const users = names.map((name, i) => ({ id: i, name }));10console.log(users);
```

Execution

Terminal window

```
node arrow-obj.js
```

Output

```
1{ name: 'Alice', age: 30 }2[ { id: 0, name: 'Alice' }, { id: 1, name: 'Bob' } ]
```

-   Without parentheses, {} is treated as a function body, not an object.
-   This pattern is very common with .map(), .filter(), and .reduce().

### Default Parameters

Setting default values for function parameters.

#### Accessibility

Default parameters make function contracts explicit.

#### Best Practices

-   Use default parameters instead of checking for undefined manually.
-   Use rest parameters instead of the arguments object.
-   Put parameters with defaults at the end.

#### Common Errors

-   **Expecting null to trigger default values:** Only undefined triggers defaults. Use ?? operator for null handling.
-   **Putting rest parameter before other parameters:** Rest parameter must be last in the parameter list.

#### Keywords

defaultparameterargumentfallbackoptional

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters)

#### Default parameter values

Default parameters are used when arguments are undefined or not provided. They can reference earlier parameters.

Code

```
1function greet(name = 'World', greeting = 'Hello') {2  return `${greeting}, ${name}!`;3}4
5console.log(greet());              // "Hello, World!"6console.log(greet('Alice'));        // "Hello, Alice!"7console.log(greet('Bob', 'Hi'));   // "Hi, Bob!"8
9// Defaults can use previous parameters10function createUser(name, role = 'user', id = Date.now()) {11  return { name, role, id };12}
```

Execution

Terminal window

```
node defaults.js
```

Output

```
1Hello, World!2Hello, Alice!3Hi, Bob!
```

-   null does NOT trigger defaults, only undefined does.
-   Default values are evaluated at call time, not definition time.

#### Rest parameters

Rest parameters (...name) collect remaining arguments into a real array. Must be the last parameter.

Code

```
1function sum(...numbers) {2  return numbers.reduce((total, n) => total + n, 0);3}4
5console.log(sum(1, 2, 3));     // 66console.log(sum(10, 20));       // 307
8function tag(name, ...attrs) {9  return `<${name} ${attrs.join(' ')}>`;10}11
12console.log(tag('div', 'class="box"', 'id="main"'));
```

Execution

Terminal window

```
node rest.js
```

Output

```
162303<div class="box" id="main">
```

-   Rest parameters replace the old arguments object.
-   Unlike arguments, rest parameters are a real Array.

### Closures

Functions that capture variables from their enclosing scope.

#### Accessibility

Closures enable data privacy and encapsulation patterns.

#### Best Practices

-   Use closures for data privacy and encapsulation.
-   Be aware of memory implications when closures capture large scopes.
-   Use factory functions to create specialized versions of functions.

#### Common Errors

-   **Closures in loops capturing the same variable:** Use let (block-scoped) instead of var, or create a new scope with IIFE.
-   **Memory leaks from closures holding references to large objects:** Set captured variables to null when no longer needed.

#### Keywords

closurescopelexicalencapsulationfactoryprivate

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures)

#### Basic closure

The inner functions close over the count variable, maintaining access to it even after createCounter returns.

Code

```
1function createCounter() {2  let count = 0;3  return {4    increment: () => ++count,5    decrement: () => --count,6    getCount: () => count7  };8}9
10const counter = createCounter();11console.log(counter.increment()); // 112console.log(counter.increment()); // 213console.log(counter.decrement()); // 114console.log(counter.getCount());  // 1
```

Execution

Terminal window

```
node closure.js
```

Output

```
11223141
```

-   count is private and cannot be accessed directly from outside.
-   Each call to createCounter creates a new independent scope.

#### Factory function with closure

Each call to multiplier creates a new closure capturing its own factor value.

Code

```
1function multiplier(factor) {2  return (number) => number * factor;3}4
5const double = multiplier(2);6const triple = multiplier(3);7
8console.log(double(5));  // 109console.log(triple(5));  // 1510console.log(double(10)); // 20
```

Execution

Terminal window

```
node factory.js
```

Output

```
110215320
```

-   Closures are the basis for many functional programming patterns.
-   They enable partial application and currying.

## Objects and Arrays

Object manipulation, destructuring, spread operator, and array methods.

### Destructuring

Extract values from objects and arrays into variables.

#### Accessibility

Destructuring makes data extraction explicit and readable.

#### Best Practices

-   Use destructuring in function parameters for clarity.
-   Provide default values for potentially missing properties.
-   Keep destructuring patterns reasonably shallow for readability.

#### Common Errors

-   **Destructuring null or undefined throws a TypeError:** Use default values or check for null/undefined before destructuring.
-   **Deep nested destructuring becomes hard to read:** Destructure in multiple steps for deeply nested objects.

#### Keywords

destructuringextractunpackobjectarrayrenamedefault

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)

#### Object destructuring

Object destructuring extracts properties into variables. Supports renaming, defaults, and nesting.

Code

```
1const user = { name: 'Alice', age: 30, city: 'NYC' };2
3// Basic destructuring4const { name, age } = user;5console.log(name, age); // "Alice" 306
7// Rename variables8const { name: userName, age: userAge } = user;9console.log(userName); // "Alice"10
11// Default values12const { name: n, role = 'user' } = user;13console.log(role); // "user"14
15// Nested destructuring16const data = { a: { b: { c: 42 } } };17const { a: { b: { c } } } = data;18console.log(c); // 42
```

Execution

Terminal window

```
node destruct.js
```

Output

```
1Alice 302Alice3user442
```

-   Destructuring works in function parameters too.
-   Use rest pattern { a, ...rest } to collect remaining properties.

#### Array destructuring

Array destructuring uses position to extract values. Supports skipping, rest patterns, and variable swapping.

Code

```
1const colors = ['red', 'green', 'blue', 'yellow'];2
3// Basic4const [first, second] = colors;5console.log(first, second); // "red" "green"6
7// Skip elements8const [, , third] = colors;9console.log(third); // "blue"10
11// Rest pattern12const [head, ...tail] = colors;13console.log(tail); // ["green", "blue", "yellow"]14
15// Swap variables16let a = 1, b = 2;17[a, b] = [b, a];18console.log(a, b); // 2 1
```

Execution

Terminal window

```
node array-destruct.js
```

Output

```
1red green2blue3["green", "blue", "yellow"]42 1
```

-   Array destructuring works with any iterable (strings, maps, sets).
-   The swap pattern avoids needing a temporary variable.

### Spread and Rest

The spread (...) operator for expanding and collecting elements.

#### Accessibility

Spread makes data merging and cloning explicit.

#### Best Practices

-   Use spread for immutable operations (clone then modify).
-   Use rest parameters instead of the arguments object.
-   Remember spread only does shallow copies.

#### Common Errors

-   **Expecting spread to deep clone nested objects:** Use structuredClone() or a library for deep cloning.
-   **Mutating the original when using spread on nested objects:** Spread nested objects too or use structuredClone().

#### Keywords

spreadrestmergeclonecopyexpandcollect

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax)

#### Spread with arrays and objects

Spread expands iterables into individual elements. For objects, later properties override earlier ones.

Code

```
1// Array spread2const arr1 = [1, 2, 3];3const arr2 = [4, 5, 6];4const merged = [...arr1, ...arr2];5console.log(merged); // [1, 2, 3, 4, 5, 6]6
7// Array clone8const clone = [...arr1];9
10// Object spread11const defaults = { theme: 'dark', lang: 'en' };12const userPrefs = { lang: 'fr', fontSize: 14 };13const config = { ...defaults, ...userPrefs };14console.log(config);15// { theme: 'dark', lang: 'fr', fontSize: 14 }
```

Execution

Terminal window

```
node spread.js
```

Output

```
1[1, 2, 3, 4, 5, 6]2{ theme: 'dark', lang: 'fr', fontSize: 14 }
```

-   Spread creates shallow copies, not deep clones.
-   Object spread is commonly used for immutable state updates.

#### Rest in function parameters and destructuring

Rest collects multiple elements into an array or object. Used in function parameters and destructuring.

Code

```
1// Rest in functions2function log(first, ...rest) {3  console.log('First:', first);4  console.log('Rest:', rest);5}6log('a', 'b', 'c');7
8// Rest in destructuring9const { a, ...others } = { a: 1, b: 2, c: 3 };10console.log(others); // { b: 2, c: 3 }
```

Execution

Terminal window

```
node rest-spread.js
```

Output

```
1First: a2Rest: ["b", "c"]3{ b: 2, c: 3 }
```

-   Rest must be the last element in destructuring or parameter lists.
-   Rest in objects omits the explicitly destructured keys.

### Array Methods

Essential array methods for transformation, filtering, and reduction.

#### Accessibility

Array methods provide declarative data processing.

#### Best Practices

-   Prefer map/filter over forEach when building new arrays.
-   Always provide an initial value for reduce.
-   Chain methods for readable data pipelines.

#### Common Errors

-   **Forgetting the initial value in reduce:** Always pass an initial value as the second argument to reduce.
-   **Using forEach when map or filter is more appropriate:** Use map to transform and filter to select. Reserve forEach for side effects.

#### Keywords

mapfilterreducefindsomeeveryforEachflatincludes

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array)

#### Transform and filter

map transforms, filter selects, find returns first match, some/every test conditions, includes checks membership.

Code

```
1const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];2
3// map - transform each element4const doubled = numbers.map(n => n * 2);5console.log(doubled); // [2, 4, 6, ..., 20]6
7// filter - keep matching elements8const evens = numbers.filter(n => n % 2 === 0);9console.log(evens); // [2, 4, 6, 8, 10]10
11// find - first match12const found = numbers.find(n => n > 3);13console.log(found); // 414
15// some / every16console.log(numbers.some(n => n > 5));  // true17console.log(numbers.every(n => n > 0)); // true18
19// includes20console.log(numbers.includes(5)); // true
```

Execution

Terminal window

```
node array-methods.js
```

Output

```
1[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]2[2, 4, 6, 8, 10]344true5true6true
```

-   These methods do not mutate the original array.
-   Chain methods for expressive data processing pipelines.

#### Reduce and flat

reduce accumulates array values. flat flattens nested arrays. flatMap maps and flattens in one step.

Code

```
1const numbers = [1, 2, 3, 4, 5];2
3// reduce - accumulate to single value4const sum = numbers.reduce((acc, n) => acc + n, 0);5console.log(sum); // 156
7// reduce - group by8const people = [9  { name: 'Alice', dept: 'eng' },10  { name: 'Bob', dept: 'eng' },11  { name: 'Carol', dept: 'hr' }12];13const byDept = people.reduce((groups, person) => {14  (groups[person.dept] ??= []).push(person);15  return groups;16}, {});17console.log(byDept);18
19// flat and flatMap20const nested = [[1, 2], [3, [4, 5]]];21console.log(nested.flat());    // [1, 2, 3, [4, 5]]22console.log(nested.flat(Infinity)); // [1, 2, 3, 4, 5]23
24const sentences = ['hello world', 'foo bar'];25const words = sentences.flatMap(s => s.split(' '));26console.log(words); // ["hello", "world", "foo", "bar"]
```

Execution

Terminal window

```
node reduce.js
```

Output

```
1152{ eng: [{...}, {...}], hr: [{...}] }3[1, 2, 3, [4, 5]]4[1, 2, 3, 4, 5]5["hello", "world", "foo", "bar"]
```

-   Always provide an initial value for reduce.
-   Use Object.groupBy() (ES2024) instead of reduce for grouping when available.

### Object Methods

Common Object static methods for working with objects.

#### Accessibility

Object methods provide standard ways to inspect and transform objects.

#### Best Practices

-   Use property shorthand when variable names match property names.
-   Use Object.freeze() for truly constant objects.
-   Prefer Object.entries() for iterating objects with both key and value.

#### Common Errors

-   **Assuming Object.freeze() is deep:** Object.freeze() is shallow. Use structuredClone + freeze or a library for deep freeze.
-   **Forgetting that Object.keys() returns strings:** Numeric keys are converted to strings. Use Map if you need non-string keys.

#### Keywords

Object.keysObject.valuesObject.entriesObject.assignObject.freezecomputed property

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)

#### Object inspection methods

Object.keys/values/entries return arrays for iteration. Object.fromEntries converts entries back to an object.

Code

```
1const user = { name: 'Alice', age: 30, city: 'NYC' };2
3console.log(Object.keys(user));4// ["name", "age", "city"]5
6console.log(Object.values(user));7// ["Alice", 30, "NYC"]8
9console.log(Object.entries(user));10// [["name","Alice"], ["age",30], ["city","NYC"]]11
12// Convert entries back to object13const filtered = Object.fromEntries(14  Object.entries(user).filter(([k, v]) => typeof v === 'string')15);16console.log(filtered); // { name: 'Alice', city: 'NYC' }
```

Execution

Terminal window

```
node object-methods.js
```

Output

```
1["name", "age", "city"]2["Alice", 30, "NYC"]3[["name","Alice"], ["age",30], ["city","NYC"]]4{ name: 'Alice', city: 'NYC' }
```

-   These methods only return own enumerable properties.
-   Object.entries + fromEntries works well for transforming objects.

#### Computed properties and shorthand

Property shorthand, computed names, and method shorthand make object creation more concise.

Code

```
1// Property shorthand2const name = 'Alice';3const age = 30;4const user = { name, age };5console.log(user); // { name: 'Alice', age: 30 }6
7// Computed property names8const key = 'color';9const obj = { [key]: 'blue', [`${key}Code`]: '#00f' };10console.log(obj); // { color: 'blue', colorCode: '#00f' }11
12// Method shorthand13const calc = {14  value: 0,15  add(n) { this.value += n; return this; },16  subtract(n) { this.value -= n; return this; }17};18calc.add(5).subtract(2);19console.log(calc.value); // 3
```

Execution

Terminal window

```
node computed.js
```

Output

```
1{ name: 'Alice', age: 30 }2{ color: 'blue', colorCode: '#00f' }33
```

-   Computed properties can use any expression inside brackets.
-   Method shorthand has the same this behavior as regular functions.

## Async JavaScript

Promises, async/await, and asynchronous patterns.

### Promises

Creating and chaining promises for asynchronous operations.

#### Accessibility

Promises provide structured async flow visible in code.

#### Best Practices

-   Always handle rejections with .catch() or try/catch.
-   Use Promise.all for parallel independent async tasks.
-   Use Promise.allSettled when all results matter regardless of success.

#### Common Errors

-   **Unhandled promise rejection:** Always add .catch() at the end of promise chains.
-   **Using Promise.all when one failure should not cancel others:** Use Promise.allSettled instead.

#### Keywords

promisethencatchfinallyresolverejectasync

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)

#### Creating and using promises

Promises represent eventual completion or failure. Use .then() for success, .catch() for errors, .finally() for cleanup.

Code

```
1// Creating a promise2const fetchData = new Promise((resolve, reject) => {3  setTimeout(() => {4    const success = true;5    if (success) {6      resolve({ id: 1, name: 'Alice' });7    } else {8      reject(new Error('Failed to fetch'));9    }10  }, 1000);11});12
13// Consuming with .then/.catch/.finally14fetchData15  .then(data => console.log('Data:', data))16  .catch(err => console.error('Error:', err))17  .finally(() => console.log('Done'));
```

Execution

Terminal window

```
node promise.js
```

Output

```
1Data: { id: 1, name: 'Alice' }2Done
```

-   Promises are always asynchronous, even if resolved immediately.
-   .catch() catches any error in the preceding chain.

#### Promise combinators

Promise.all fails on any rejection. allSettled waits for all. race returns the fastest. any returns first fulfillment.

Code

```
1const p1 = Promise.resolve(1);2const p2 = Promise.resolve(2);3const p3 = Promise.reject('error');4
5// all - waits for all (fails fast)6Promise.all([p1, p2])7  .then(console.log); // [1, 2]8
9// allSettled - waits for all regardless10Promise.allSettled([p1, p3])11  .then(console.log);12// [{status:'fulfilled',value:1}, {status:'rejected',reason:'error'}]13
14// race - first to settle15Promise.race([p1, p2])16  .then(console.log); // 117
18// any - first to fulfill19Promise.any([p3, p1])20  .then(console.log); // 1
```

Execution

Terminal window

```
node combinators.js
```

Output

```
1[1, 2]2[{status:'fulfilled',value:1},{status:'rejected',reason:'error'}]3141
```

-   Use Promise.all for parallel independent async operations.
-   Use Promise.allSettled when you need results regardless of individual failures.

### Async/Await

Syntactic sugar over promises for cleaner asynchronous code.

#### Accessibility

Async/await makes async code read like synchronous code.

#### Best Practices

-   Use Promise.all for independent parallel operations.
-   Always wrap await in try/catch for error handling.
-   Avoid await in loops; prefer Promise.all with map.

#### Common Errors

-   **Using await in a forEach loop (does not work as expected):** Use for...of loop or Promise.all(array.map(async ...)) instead.
-   **Sequential awaits for independent operations:** Use Promise.all to run independent operations in parallel.

#### Keywords

asyncawaittrycatchasynchronoussequentialparallel

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function)

#### Basic async/await

async functions always return promises. await pauses execution until the promise resolves. Use try/catch for error handling.

Code

```
1async function fetchUser(id) {2  try {3    const response = await fetch(`/api/users/${id}`);4    if (!response.ok) throw new Error('Not found');5    const user = await response.json();6    return user;7  } catch (error) {8    console.error('Failed:', error.message);9    return null;10  }11}12
13// Arrow async function14const getUser = async (id) => {15  const res = await fetch(`/api/users/${id}`);16  return res.json();17};18
19// Top-level await (in modules)20const data = await fetchUser(1);
```

-   Top-level await works in ES modules only.
-   async/await is syntactic sugar over promises.

#### Sequential vs parallel execution

Use Promise.all with await for parallel execution of independent async operations. Sequential await is appropriate when operations depend on each other.

Code

```
1// Sequential (slow - one after another)2async function sequential() {3  const user = await fetchUser(1);    // waits...4  const posts = await fetchPosts(1);  // then waits...5  return { user, posts };6}7
8// Parallel (fast - both at once)9async function parallel() {10  const [user, posts] = await Promise.all([11    fetchUser(1),12    fetchPosts(1)13  ]);14  return { user, posts };15}16
17// Parallel with error handling18async function parallelSafe() {19  const results = await Promise.allSettled([20    fetchUser(1),21    fetchPosts(1)22  ]);23  return results.map(r =>24    r.status === 'fulfilled' ? r.value : null25  );26}
```

-   With parallel execution the total time is the slowest operation, not the sum of all of them.
-   Use for...of with await for sequential iteration over async operations.

## Classes and Modules

ES6 classes, inheritance, and module import/export syntax.

### Classes

ES6 class syntax for object-oriented programming.

#### Accessibility

Classes provide familiar OOP syntax for code organization.

#### Best Practices

-   Use private fields (#) for encapsulation.
-   Prefer composition over deep inheritance hierarchies.
-   Use static methods for utility functions related to the class.

#### Common Errors

-   **Forgetting to call super() in derived class constructor:** Always call super() before using this in derived class constructors.
-   **Using arrow functions for class methods that need to be overridden:** Use regular method syntax for overridable methods.

#### Keywords

classconstructorextendssuperstaticgettersetterprivate

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes)

#### Class declaration and inheritance

Classes support private fields (#), getters/setters, static methods, and inheritance via extends/super.

Code

```
1class Animal {2  #name;  // private field3
4  constructor(name) {5    this.#name = name;6  }7
8  get name() { return this.#name; }9  set name(value) { this.#name = value; }10
11  speak() {12    return `${this.#name} makes a sound`;13  }14
15  static create(name) {16    return new Animal(name);17  }18}19
20class Dog extends Animal {21  #breed;22
23  constructor(name, breed) {24    super(name);25    this.#breed = breed;26  }27
28  speak() {29    return `${this.name} barks`;30  }31
32  info() {33    return `${this.name} is a ${this.#breed}`;34  }35}36
37const dog = new Dog('Rex', 'Labrador');38console.log(dog.speak());  // "Rex barks"39console.log(dog.info());   // "Rex is a Labrador"40
41const cat = Animal.create('Whiskers');42console.log(cat.speak());  // "Whiskers makes a sound"
```

Execution

Terminal window

```
node classes.js
```

Output

```
1Rex barks2Rex is a Labrador3Whiskers makes a sound
```

-   Private fields (#) are truly private and not accessible outside the class.
-   Static methods are called on the class, not instances.

#### Class with static and instance methods

A practical class example implementing a simple event emitter with method chaining (returning this).

Code

```
1class EventEmitter {2  #listeners = new Map();3
4  on(event, callback) {5    if (!this.#listeners.has(event)) {6      this.#listeners.set(event, []);7    }8    this.#listeners.get(event).push(callback);9    return this;10  }11
12  emit(event, ...args) {13    const handlers = this.#listeners.get(event) ?? [];14    handlers.forEach(fn => fn(...args));15    return this;16  }17
18  off(event, callback) {19    const handlers = this.#listeners.get(event) ?? [];20    this.#listeners.set(event,21      handlers.filter(fn => fn !== callback)22    );23    return this;24  }25}26
27const emitter = new EventEmitter();28emitter29  .on('data', (msg) => console.log('Received:', msg))30  .emit('data', 'hello');
```

Execution

Terminal window

```
node emitter.js
```

Output

```
1Received: hello
```

-   Method chaining is enabled by returning this.
-   The private Map keeps listeners inside the class.

### Modules

ES6 module import/export syntax.

#### Accessibility

Modules organize code into reusable, isolated units.

#### Best Practices

-   Prefer named exports over default exports for better refactoring.
-   Use dynamic imports for code splitting and lazy loading.
-   Create barrel files (index.js) for module directories.

#### Common Errors

-   **Mixing CommonJS require() with ES module import:** Use one module system consistently. Set "type":"module" in package.json for ESM.
-   **Circular dependencies between modules:** Extract shared code into a separate module or restructure the dependency graph.

#### Keywords

importexportdefaultnamedmoduledynamicre-export

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules)

#### Named and default exports

Named exports allow multiple exports per module. Default exports are imported without braces. Use as to rename imports.

Code

```
1// math.js - Named exports2export const PI = 3.14159;3export function add(a, b) { return a + b; }4export function multiply(a, b) { return a * b; }5
6// utils.js - Default export7export default class Logger {8  log(msg) { console.log(`[LOG] ${msg}`); }9}10
11// app.js - Importing12import Logger from './utils.js';            // default13import { add, multiply, PI } from './math.js'; // named14import { add as sum } from './math.js';        // rename15import * as math from './math.js';             // namespace16
17console.log(math.add(2, 3));  // 518console.log(sum(2, 3));        // 519console.log(PI);               // 3.14159
```

-   A module can have one default export and many named exports.
-   Use namespace import (\* as) to import all named exports.

#### Dynamic imports and re-exports

Dynamic imports return a promise and enable code splitting. Re-exports create barrel files for cleaner imports.

Code

```
1// Dynamic import (code splitting)2async function loadModule() {3  const { add } = await import('./math.js');4  console.log(add(2, 3)); // 55}6
7// Conditional import8const lang = 'en';9const messages = await import(`./i18n/${lang}.js`);10
11// Re-exports (index.js barrel file)12export { add, multiply } from './math.js';13export { default as Logger } from './utils.js';14export * from './helpers.js'; // re-export all
```

-   Dynamic imports enable lazy loading in web apps.
-   Barrel files (index.js) simplify imports from complex modules.

## Error Handling

Try/catch, custom errors, and error handling patterns.

### Try/Catch

Exception handling with try, catch, and finally blocks.

#### Accessibility

Proper error handling ensures graceful failure.

#### Best Practices

-   Create custom error classes for different error categories.
-   Always re-throw errors you do not handle.
-   Use finally for cleanup operations.

#### Common Errors

-   **Catching errors without re-throwing unknown ones:** Only catch specific error types, re-throw everything else.
-   **Using try/catch for control flow:** Use conditional checks for expected conditions, try/catch for unexpected errors.

#### Keywords

trycatchfinallythrowerrorexception

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/try...catch)

#### Basic error handling

try/catch handles runtime errors. finally always executes. throw creates custom errors.

Code

```
1try {2  const data = JSON.parse('invalid json');3} catch (error) {4  console.error('Parse error:', error.message);5} finally {6  console.log('Always runs');7}8
9// Throwing custom errors10function divide(a, b) {11  if (b === 0) throw new Error('Division by zero');12  return a / b;13}14
15try {16  console.log(divide(10, 0));17} catch (e) {18  console.error(e.message); // "Division by zero"19}
```

Execution

Terminal window

```
node errors.js
```

Output

```
1Parse error: Unexpected token i in JSON at position 02Always runs3Division by zero
```

-   finally runs whether or not an error occurred.
-   Use specific error types for different error categories.

#### Custom error classes

Custom error classes extend Error for domain-specific error types. Use instanceof to handle specific error types.

Code

```
1class ValidationError extends Error {2  constructor(field, message) {3    super(message);4    this.name = 'ValidationError';5    this.field = field;6  }7}8
9class NotFoundError extends Error {10  constructor(resource) {11    super(`${resource} not found`);12    this.name = 'NotFoundError';13    this.statusCode = 404;14  }15}16
17function validate(user) {18  if (!user.name) throw new ValidationError('name', 'Name required');19  if (!user.email) throw new ValidationError('email', 'Email required');20}21
22try {23  validate({ name: '' });24} catch (e) {25  if (e instanceof ValidationError) {26    console.log(`${e.field}: ${e.message}`);27  } else {28    throw e; // re-throw unknown errors29  }30}
```

Execution

Terminal window

```
node custom-error.js
```

Output

```
1name: Name required
```

-   Always set this.name in custom errors for better debugging.
-   Re-throw errors you cannot handle at the current level.

## Iterators and Generators

Iteration protocols, generators, and advanced iteration patterns.

### Iterators

The iteration protocol and creating custom iterables.

#### Accessibility

Iterators provide a standard way to traverse data structures.

#### Best Practices

-   Implement Symbol.iterator for custom collections.
-   Use for...of instead of for...in for iterables.
-   \[object Object\]

#### Common Errors

-   **Using for...in instead of for...of for arrays:** for...in iterates keys/properties; for...of iterates values.
-   **Forgetting to return { done: true } to end iteration:** Always return { done: true } when there are no more values.

#### Keywords

iteratoriterableSymbol.iteratorfor..ofnextdonevalue

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols)

#### Custom iterable

Objects implementing \[Symbol.iterator\]() are iterable and work with for...of, spread, and destructuring.

Code

```
1class Range {2  constructor(start, end) {3    this.start = start;4    this.end = end;5  }6
7  [Symbol.iterator]() {8    let current = this.start;9    const end = this.end;10    return {11      next() {12        if (current <= end) {13          return { value: current++, done: false };14        }15        return { done: true };16      }17    };18  }19}20
21const range = new Range(1, 5);22for (const n of range) {23  process.stdout.write(`${n} `);24}25// 1 2 3 4 526
27console.log([...range]); // [1, 2, 3, 4, 5]
```

Execution

Terminal window

```
node iterator.js
```

Output

```
11 2 3 4 52[1, 2, 3, 4, 5]
```

-   Built-in iterables include Array, String, Map, Set, and NodeList.
-   Spread operator and destructuring consume iterables.

### Generators

Generator functions that can pause and resume execution.

#### Accessibility

Generators enable lazy evaluation and custom iteration.

#### Best Practices

-   Use generators for lazy evaluation of large or infinite sequences.
-   Use async generators for streaming async data.
-   Combine generators with helper functions like take, filter, map.

#### Common Errors

-   **Forgetting the asterisk in function\* declaration:** Generator functions require the \* syntax: function\* name() {}.
-   **Not consuming the generator (calling it returns an iterator, not a value):** Call .next() or use for...of to consume generator values.

#### Keywords

generatoryieldfunction\*nextlazyinfiniteasync generator

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator)

#### Generator basics

Generator functions (function\*) use yield to pause execution. Each next() call resumes until the next yield.

Code

```
1function* count(start = 0) {2  let i = start;3  while (true) {4    yield i++;5  }6}7
8const counter = count(1);9console.log(counter.next().value); // 110console.log(counter.next().value); // 211console.log(counter.next().value); // 312
13// Take first N from infinite generator14function* take(iterable, n) {15  let i = 0;16  for (const value of iterable) {17    if (i++ >= n) return;18    yield value;19  }20}21
22console.log([...take(count(10), 5)]);23// [10, 11, 12, 13, 14]
```

Execution

Terminal window

```
node generator.js
```

Output

```
1122334[10, 11, 12, 13, 14]
```

-   Generators are lazy; they only compute values on demand.
-   Infinite generators are safe because they only produce values when consumed.

#### Async generators

Async generators combine async/await with generator syntax. Use for await...of to consume them.

Code

```
1async function* fetchPages(url) {2  let page = 1;3  while (true) {4    const res = await fetch(`${url}?page=${page}`);5    const data = await res.json();6    if (data.length === 0) return;7    yield data;8    page++;9  }10}11
12// Consuming async generator13async function getAllPages() {14  const pages = [];15  for await (const page of fetchPages('/api/items')) {16    pages.push(...page);17    if (pages.length > 100) break;18  }19  return pages;20}
```

-   Async generators suit paginated API calls.
-   for await...of works with any async iterable.

## Modern Features

Recent JavaScript features including Map, Set, Proxy, and other ES2020+ additions.

### Map and Set

Map and Set collections for unique values and key-value pairs.

#### Accessibility

Map and Set provide optimized collection types.

#### Best Practices

-   Use Set for collections of unique values.
-   Use Map when keys are not strings or you need ordered key-value pairs.
-   Prefer Map over plain objects for dynamic key-value storage.

#### Common Errors

-   **Expecting Set to deduplicate objects by value:** Set uses reference equality for objects. Two identical objects are treated as different.
-   **Using map\[key\] syntax instead of map.get(key):** Map uses .get()/.set()/.has() methods, not bracket notation.

#### Keywords

MapSetWeakMapWeakSetcollectionuniquekey-value

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map)

#### Map usage

Map allows any type as keys, maintains insertion order, and gives fast key lookup.

Code

```
1const map = new Map();2
3// Any value can be a key4map.set('name', 'Alice');5map.set(42, 'the answer');6map.set(true, 'yes');7
8console.log(map.get('name'));  // "Alice"9console.log(map.has(42));      // true10console.log(map.size);         // 311
12// Initialize from entries13const config = new Map([14  ['theme', 'dark'],15  ['lang', 'en'],16  ['debug', false]17]);18
19// Iteration20for (const [key, value] of config) {21  console.log(`${key}: ${value}`);22}23
24// Convert to/from object25const obj = Object.fromEntries(config);26const map2 = new Map(Object.entries(obj));
```

Execution

Terminal window

```
node map.js
```

Output

```
1Alice2true334theme: dark5lang: en6debug: false
```

-   Map is better than objects when keys are not strings.
-   Use map.size instead of Object.keys(obj).length.

#### Set usage

Set stores unique values of any type. Useful for deduplication and membership testing.

Code

```
1// Unique values2const set = new Set([1, 2, 3, 2, 1]);3console.log([...set]); // [1, 2, 3]4
5set.add(4);6set.delete(1);7console.log(set.has(2));  // true8console.log(set.size);    // 39
10// Array deduplication11const arr = [1, 1, 2, 3, 3, 4];12const unique = [...new Set(arr)];13console.log(unique); // [1, 2, 3, 4]14
15// Set operations (ES2025+)16const a = new Set([1, 2, 3]);17const b = new Set([2, 3, 4]);18console.log([...a.intersection(b)]);  // [2, 3]19console.log([...a.union(b)]);          // [1, 2, 3, 4]20console.log([...a.difference(b)]);     // [1]
```

Execution

Terminal window

```
node set.js
```

Output

```
1[1, 2, 3]2true334[1, 2, 3, 4]5[2, 3]6[1, 2, 3, 4]7[1]
```

-   Set uses SameValueZero comparison (similar to ===).
-   Set operations (union, intersection, difference) are available in modern engines.

### Proxy and Reflect

Metaprogramming with Proxy and Reflect for intercepting operations.

#### Accessibility

Proxy enables transparent object behavior customization.

#### Best Practices

-   Use Proxy for cross-cutting concerns like validation, logging, or reactivity.
-   Use Reflect inside traps for consistent default behavior.
-   Document proxy behavior clearly as it can be surprising.

#### Common Errors

-   **Forgetting to return true from set trap:** The set trap must return true to indicate success in strict mode.
-   **Infinite loops when proxy triggers itself:** Use a flag or WeakSet to track in-progress operations.

#### Keywords

ProxyReflecthandlertrapgetsetmetaprogramming

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy)

#### Validation proxy

Proxy intercepts operations (get, set, delete, etc.) on objects. Handlers define traps for each operation.

Code

```
1const validator = {2  set(target, prop, value) {3    if (prop === 'age') {4      if (typeof value !== 'number') {5        throw new TypeError('Age must be a number');6      }7      if (value < 0 || value > 150) {8        throw new RangeError('Age must be 0-150');9      }10    }11    target[prop] = value;12    return true;13  },14  get(target, prop) {15    if (prop in target) return target[prop];16    throw new ReferenceError(`Property ${prop} not found`);17  }18};19
20const user = new Proxy({}, validator);21user.name = 'Alice';22user.age = 30;23console.log(user.name); // "Alice"24
25try { user.age = -5; } catch (e) {26  console.log(e.message); // "Age must be 0-150"27}
```

Execution

Terminal window

```
node proxy.js
```

Output

```
1Alice2Age must be 0-150
```

-   Proxies are used in Vue 3 reactivity and MobX state management.
-   Use Reflect methods inside traps for default behavior.

#### Reactive proxy with onChange

A reactive proxy that calls onChange whenever properties are modified. This is how modern reactivity systems work.

Code

```
1function reactive(target, onChange) {2  return new Proxy(target, {3    set(obj, prop, value) {4      const oldValue = obj[prop];5      obj[prop] = value;6      if (oldValue !== value) {7        onChange(prop, value, oldValue);8      }9      return true;10    },11    deleteProperty(obj, prop) {12      const value = obj[prop];13      delete obj[prop];14      onChange(prop, undefined, value);15      return true;16    }17  });18}19
20const state = reactive({ count: 0 }, (prop, newVal, oldVal) => {21  console.log(`${prop}: ${oldVal} -> ${newVal}`);22});23
24state.count = 1;  // "count: 0 -> 1"25state.count = 5;  // "count: 1 -> 5"
```

Execution

Terminal window

```
node reactive.js
```

Output

```
1count: 0 -> 12count: 1 -> 5
```

-   This pattern is the basis of Vue 3 and similar frameworks.
-   Add deep proxy wrapping for nested reactivity.

### Miscellaneous Modern Features

Useful modern JavaScript features and syntax.

#### Accessibility

Modern features improve code expressiveness and safety.

#### Best Practices

-   Use structuredClone instead of JSON.parse(JSON.stringify()) for deep cloning.
-   Use .at(-1) instead of arr\[arr.length - 1\] for last element access.
-   Use Object.groupBy when available instead of manual reduce.

#### Common Errors

-   **Expecting structuredClone to clone functions or DOM nodes:** structuredClone works with structured-cloneable types only. Functions cannot be cloned.
-   **Using ||= when 0 or empty string are valid values:** Use ??= which only checks for null/undefined.

#### Keywords

structuredCloneatgroupByusingwithglobalThis

[Learn more](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)

#### Useful modern additions

Modern JS includes structuredClone for deep copying, .at() for negative indexing, Object.groupBy for grouping, and more.

Code

```
1// structuredClone - deep clone2const original = { a: { b: { c: 1 } }, d: [2, 3] };3const clone = structuredClone(original);4clone.a.b.c = 99;5console.log(original.a.b.c); // 1 (unchanged)6
7// Array.at() - negative indexing8const arr = [1, 2, 3, 4, 5];9console.log(arr.at(-1));  // 510console.log(arr.at(-2));  // 411
12// Object.groupBy (ES2024)13const people = [14  { name: 'Alice', age: 30 },15  { name: 'Bob', age: 25 },16  { name: 'Carol', age: 30 }17];18const byAge = Object.groupBy(people, p => p.age);19console.log(byAge[30]); // [Alice, Carol]20
21// String.replaceAll22const str = 'foo-bar-baz';23console.log(str.replaceAll('-', '_')); // "foo_bar_baz"
```

Execution

Terminal window

```
node modern.js
```

Output

```
1125344[{name:'Alice',age:30},{name:'Carol',age:30}]5foo_bar_baz
```

-   structuredClone handles circular references but cannot clone functions.
-   Object.groupBy replaces manual reduce-based grouping.

#### Pattern matching with switch(true) and logical assignment

Logical assignment operators combine logical operations with assignment. switch(true) enables range-based matching.

Code

```
1// Logical assignment operators2let a = null;3a ??= 'default';    // a = 'default' (null/undefined)4console.log(a);5
6let b = 0;7b ||= 42;           // b = 42 (falsy)8console.log(b);9
10let c = 1;11c &&= 2;            // c = 2 (truthy)12console.log(c);13
14// switch(true) pattern15const score = 85;16switch (true) {17  case score >= 90: console.log('A'); break;18  case score >= 80: console.log('B'); break;19  case score >= 70: console.log('C'); break;20  default: console.log('F');21}
```

Execution

Terminal window

```
node logical.js
```

Output

```
1default242324B
```

-   ??= assigns only if null/undefined.
-   ||= assigns if falsy (including 0, "", false).
-   &&= assigns only if truthy.

Was this useful?

## Tags

#JavaScript#ES6#Web Development#Frontend#Node.js#Programming

## Share

[Facebook](https://facebook.com/sharer/sharer.php?u=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Fjavascript "Share on Facebook")[Twitter](https://twitter.com/intent/tweet/?text=JavaScript&url=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Fjavascript "Share on Twitter")[LinkedIn](https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Fjavascript&title=JavaScript&summary=JavaScript%20is%20a%20high-level%20programming%20language%20that%20powers%20the%20web.%20It%20supports%20object-oriented%2C%20functional%2C%20and%20event-driven%20programming%20styles.&source=https://mkabumattar.com "Share on LinkedIn")[WhatsApp](https://wa.me/?text=JavaScript%20https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Fjavascript "Share on WhatsApp")[Telegram](https://t.me/share/url?url=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Fjavascript&text=JavaScript "Share on Telegram")[Reddit](https://www.reddit.com/submit?url=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Fjavascript&title=JavaScript "Share on Reddit")[Hacker News](http://news.ycombinator.com/submitlink?u=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Fjavascript&t=JavaScript "Share on Hacker News")[Pinterest](https://pinterest.com/pin/create/button/?url=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Fjavascript&media=&description=JavaScript%20is%20a%20high-level%20programming%20language%20that%20powers%20the%20web.%20It%20supports%20object-oriented%2C%20functional%2C%20and%20event-driven%20programming%20styles. "Share on Pinterest")[Email](<mailto:?subject=JavaScript&body=Check out this article: https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Fjavascript>)

## Comments

## You might also enjoy

More posts on similar topics

## [Python](/cheatsheets/python)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   Programming Language
-   Python
-   Scripting
-   Object Oriented
-   Web Development
-   Data Science

Python is an interpreted, high-level programming language known for its readability and simplicity. It supports multiple programming paradigms including procedural, object-oriented, and functional pro

#Python#Programming#Scripting+6 tags

[read more](/cheatsheets/python)

## [Go](/cheatsheets/go)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   Programming Language
-   Go
-   Systems Programming
-   Web Development
-   Backend
-   Concurrency

Go is a statically typed, compiled programming language designed with simplicity and efficiency in mind. It excels at concurrent programming, which makes it a good fit for fast, scalable server applic

#Go#Golang#Programming+6 tags

[read more](/cheatsheets/go)

## [Dart](/cheatsheets/dart)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   Programming Language
-   Dart
-   Application Development
-   Type Safety
-   Null Safety

Dart is a statically-typed, strongly null-safe programming language designed for building fast, multi-platform applications. Created by Google, Dart ships with its own compiler, formatter, and package

#Dart#Programming#Type Safety+5 tags

[read more](/cheatsheets/dart)

## [Curl](/cheatsheets/curl)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   Terminal
-   Web Development
-   APIs
-   HTTP
-   Command Line
-   Tools

Getting started with Curl cURL (client URL) is a command-line tool for transferring data using URLs. It speaks HTTP, HTTPS, FTP, SFTP, and many other protocols, which makes it the usual choice for

#Curl#HTTP#REST+3 tags

[read more](/cheatsheets/curl)

## [AWK](/cheatsheets/awk)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   Terminal
-   Text Processing
-   Linux
-   Command Line
-   Development Tools
-   Scripting

AWK complete reference guide Quick start Print entire file awk '{ print }' file.txt# Print specific column awk '{ print $1 }' file.txt# Print lines matching pattern awk '/patter

#AWK#Text Processing#Pattern Matching+3 tags

[read more](/cheatsheets/awk)

## [Bash](/cheatsheets/bash)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   Scripting
-   Shell
-   Linux
-   Unix
-   Command Line
-   Automation

Bash is a Unix shell and command language written by Brian Fox for the GNU Project as a free software replacement for the Bourne shell. The sections below cover Bash commands, syntax, and examples.

#Scripting#Shell#Linux+3 tags

[read more](/cheatsheets/bash)

6 related posts
