JavaScript Standard Objects Reference

JavaScript ships with a set of built-in standard objects that are available in every environment — the browser, Node.js, Deno — without any import or installation. These include everyday tools like Object, Array, and String, numeric and date helpers like Math and Date, keyed collections like Map and Set, and utilities for serialization, pattern matching, and error handling. Understanding what’s built in — and how it actually works under the hood — saves you from reinventing functionality the language already gives you for free.

Overview / How It Works

Every standard object in JavaScript lives as a property on the global objectglobalThis in modern JS, window in browsers, or global in Node.js. That’s why you can type Math.random() or new Date() in any script without importing anything: the engine registers these objects before your code ever runs.

Standard objects fall into two broad categories. Some are constructor functions you invoke with new to create instances — Date, Map, Set, RegExp, and the various Error types all work this way. Others are static utility namespaces that you never instantiate — Math and JSON are plain objects full of functions; calling new Math() throws a TypeError because Math isn’t a constructor at all.

Each constructor has an associated prototype object (for example Array.prototype) that holds the methods shared by every instance. When you call [1, 2, 3].map(...), the array itself doesn’t own a map method — the engine walks up the prototype chain from the array instance to Array.prototype, finds map there, and invokes it with the array as this. This is why all arrays share behavior without duplicating code in memory.

Primitive values — strings, numbers, booleans, symbols, and bigints — are not objects and have no properties of their own. Yet "hi".toUpperCase() works because when you access a property on a primitive, the engine performs auto-boxing: it temporarily wraps the primitive in its corresponding wrapper object (String, Number, or Boolean), looks up the method on that wrapper’s prototype, runs it, and immediately discards the wrapper. This happens on every single property access on a primitive, which is one reason manually creating wrapper objects with new String(...) is discouraged — it’s redundant work the engine already does for you, and it produces a real object instead of a primitive.

Syntax

The general forms you’ll use repeatedly:

// Constructor style — build a new instance
const now = new Date();

// Static namespace — never instantiated
const rounded = Math.round(4.6);

// Wrapper methods on primitives (auto-boxing)
const shout = "hello".toUpperCase();

console.log(rounded, shout);
Category Standard objects Typical use
Fundamental Object, Function, Boolean, Symbol Building blocks for everything else
Numbers & dates Number, Math, Date, BigInt Arithmetic, formatting, time
Text String, RegExp Parsing and matching text
Indexed collections Array, typed arrays Ordered lists of values
Keyed collections Map, Set, WeakMap, WeakSet Lookups and unique value sets
Structured data JSON Serialize/deserialize objects
Control abstraction Promise, generators Asynchronous and lazy flow
Errors Error, TypeError, RangeError, etc. Signaling and catching failures
Reflection Reflect, Proxy Meta-programming

Examples

Example 1: Array, Math, Object, and JSON together

const numbers = [5, 12, 8, 1, 4];
const max = Math.max(...numbers);
const sum = numbers.reduce((total, n) => total + n, 0);
const label = `Max: ${max}, Sum: ${sum}`;

console.log(label);
console.log(Object.keys({ a: 1, b: 2 }));
console.log(JSON.stringify({ name: "Ada", active: true }));
Max: 12, Sum: 30
[ 'a', 'b' ]
{"name":"Ada","active":true}

This mixes four standard objects in a few lines: Math.max and Array.prototype.reduce compute values, Object.keys extracts an object’s own enumerable keys as an array, and JSON.stringify serializes an object into a compact text form suitable for storage or network transfer.

Example 2: Date, RegExp, and Map

const now = new Date(2024, 0, 15);
console.log(now.getFullYear(), now.getMonth(), now.getDate());

const pattern = /(\d{3})-(\d{4})/;
const match = "Call 555-1234 now".match(pattern);
console.log(match[0], match[1], match[2]);

const inventory = new Map();
inventory.set("apples", 10);
inventory.set("bananas", 5);
for (const [item, count] of inventory) {
  console.log(`${item}: ${count}`);
}
2024 0 15
555-1234 555 1234
apples: 10
bananas: 5

Note that getMonth() is zero-indexed, so January reports as 0. The RegExp‘s capture groups come back as extra elements in the match array. Map preserves insertion order during iteration, which plain objects don’t reliably guarantee for all key types.

Example 3: Error handling and Symbol

function parseAge(input) {
  const age = Number(input);
  if (Number.isNaN(age)) {
    throw new TypeError(`"${input}" is not a valid age`);
  }
  return age;
}

try {
  parseAge("twenty");
} catch (error) {
  console.log(error.name, "-", error.message);
}

const id = Symbol("id");
const user = { name: "Grace", [id]: 1001 };
console.log(user.name, user[id]);
console.log(typeof id);
TypeError - "twenty" is not a valid age
Grace 1001
symbol

TypeError is one of several built-in Error subclasses; throwing the specific subtype lets callers branch on error.name or use instanceof. Symbol creates a guaranteed-unique value, often used as an object key that won’t collide with string keys or show up in a normal for...in loop.

Under the Hood: How Method Lookup Works

When you write [1, 2].push(3), the engine doesn’t search a giant list of functions — it performs a short, deterministic walk:

  • The array instance itself is checked first for an own property called push. It doesn’t have one.
  • The engine follows the internal [[Prototype]] link to Array.prototype, which does define push.
  • That function is invoked with the array bound as this, so it can read and mutate the array’s length and indexed elements.
  • If nothing along the chain defines the property, the chain ends at Object.prototype, and finally at null — at which point the result is undefined.

This lookup happens on every property access, which is why adding a method to Array.prototype instantly makes it available on every array in the program, including ones created before the addition — they all share the same prototype object rather than owning separate copies of each method.

Common Mistakes

Mistake 1: Assuming a sized array is filled

const zeros = new Array(3).map(x => 0);
console.log(zeros);
[ <3 empty items> ]

new Array(3) creates an array with length 3 but no actual elements — just empty “holes”. Array iteration methods like map and forEach skip holes entirely, so the callback never runs and the holes pass straight through. The fix is to actually populate the array first:

const zeros = Array.from({ length: 3 }, () => 0);
console.log(zeros);
[ 0, 0, 0 ]

Mistake 2: Expecting Object.freeze to freeze deeply

const config = Object.freeze({ name: "app", settings: { debug: true } });
config.settings.debug = false;
console.log(config.settings.debug);
false

Object.freeze only locks the top-level properties of the object you pass it — nested objects are untouched and remain fully mutable. To truly lock a nested structure, freeze recursively:

function deepFreeze(obj) {
  Object.values(obj).forEach(value => {
    if (typeof value === "object" && value !== null) {
      deepFreeze(value);
    }
  });
  return Object.freeze(obj);
}

const config = deepFreeze({ name: "app", settings: { debug: true } });
config.settings.debug = false;
console.log(config.settings.debug);
true

Best Practices

  • Prefer static helpers like Array.from, Object.entries, and Number.isInteger over hand-rolled loops — they’re clearer and already handle edge cases.
  • Use Array.isArray(value) instead of value instanceof Array; the latter can fail across iframes or realms where prototype chains differ.
  • Avoid new String(), new Number(), and new Boolean() — they create boxed objects that behave surprisingly in comparisons (new Boolean(false) is truthy). Use the primitive literals instead.
  • Reach for Map when keys aren’t simple strings, or when you need guaranteed insertion order and a reliable size; reach for Set to deduplicate or test membership.
  • Remember JSON.stringify silently drops undefined, functions, and Symbol keys, and throws on circular references — don’t rely on it for deep cloning arbitrary objects.
  • Throw specific Error subclasses (TypeError, RangeError) rather than generic Error, so callers can branch on error.name or instanceof.
  • Use Object.is(NaN, NaN) or Number.isNaN() when NaN might be involved — NaN === NaN is always false.

Practice Exercises

  • Write a function sortByKey(items, key) that takes an array of objects and returns a new array sorted by the given property name, using Array.prototype.sort without mutating the original array.
  • Given an array of numbers with duplicates, use a Set to return a new array containing only the unique values, preserving their first-seen order.
  • Write a function daysUntil(targetDate) that uses the Date object to return how many whole days remain between today and a given future Date.

Summary

  • Standard objects are built into the JavaScript engine and available globally without imports.
  • Some are constructors invoked with new (Date, Map, RegExp); others are static namespaces you never instantiate (Math, JSON).
  • Methods are resolved through the prototype chain, not copied onto each instance.
  • Primitives temporarily become wrapper objects (auto-boxing) whenever you access a method on them.
  • Object.freeze is shallow, sized arrays can contain holes, and NaN never equals itself — know these gotchas before you rely on them.
  • Prefer built-in static utilities over manual implementations; they’re tested, optimized, and communicate intent clearly.