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 object — globalThis 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 toArray.prototype, which does definepush. - That function is invoked with the array bound as
this, so it can read and mutate the array’slengthand indexed elements. - If nothing along the chain defines the property, the chain ends at
Object.prototype, and finally atnull— at which point the result isundefined.
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, andNumber.isIntegerover hand-rolled loops — they’re clearer and already handle edge cases. - Use
Array.isArray(value)instead ofvalue instanceof Array; the latter can fail across iframes or realms where prototype chains differ. - Avoid
new String(),new Number(), andnew Boolean()— they create boxed objects that behave surprisingly in comparisons (new Boolean(false)is truthy). Use the primitive literals instead. - Reach for
Mapwhen keys aren’t simple strings, or when you need guaranteed insertion order and a reliablesize; reach forSetto deduplicate or test membership. - Remember
JSON.stringifysilently dropsundefined, functions, andSymbolkeys, and throws on circular references — don’t rely on it for deep cloning arbitrary objects. - Throw specific
Errorsubclasses (TypeError,RangeError) rather than genericError, so callers can branch onerror.nameorinstanceof. - Use
Object.is(NaN, NaN)orNumber.isNaN()when NaN might be involved —NaN === NaNis alwaysfalse.
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, usingArray.prototype.sortwithout mutating the original array. - Given an array of numbers with duplicates, use a
Setto return a new array containing only the unique values, preserving their first-seen order. - Write a function
daysUntil(targetDate)that uses theDateobject to return how many whole days remain between today and a given futureDate.
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.freezeis shallow, sized arrays can contain holes, andNaNnever 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.
