JavaScript Cheatsheet

Objects

Use this JavaScript reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Creating Objects

// Object literal — preferred
const obj = { name: "Alice", age: 30 };

// Shorthand when variable name matches key (ES6)
const name = "Alice";
const age = 30;
const obj2 = { name, age }; // { name: "Alice", age: 30 }

// Computed property names (ES6)
const key = "dynamic";
const obj3 = { [key]: "value", [`${key}_2`]: "v2" };

// Constructor function
function Person(name, age) {
  this.name = name;
  this.age = age;
}
const alice = new Person("Alice", 30);

// Object.create — set prototype manually
const proto = { greet() { return `Hi, I'm ${this.name}`; } };
const obj4 = Object.create(proto);
obj4.name = "Alice";

// new Object() — avoid
const obj5 = new Object(); // same as {}

Accessing and Modifying Properties

const obj = { name: "Alice", "has spaces": true };

// Dot notation
obj.name          // "Alice"
obj.missing       // undefined

// Bracket notation — required for dynamic keys or invalid identifiers
obj["name"]       // "Alice"
obj["has spaces"] // true
const key = "name";
obj[key]          // "Alice"

// Setting
obj.age = 30;
obj["email"] = "alice@example.com";

// Deleting
delete obj.age;   // removes property, returns true

// Optional chaining
obj?.address?.city  // undefined instead of error

Shorthand and Method Definitions

const x = 1, y = 2;

// Shorthand properties (ES6)
const point = { x, y }; // { x: 1, y: 2 }

// Method shorthand (ES6)
const obj = {
  name: "Alice",
  greet() {
    return `Hi, I'm ${this.name}`;
  },
  // vs old style:
  greetOld: function() { return `Hi, I'm ${this.name}`; },
};

// Getters and Setters
const person = {
  _name: "Alice",
  get name() { return this._name; },
  set name(val) {
    if (typeof val !== "string") throw new TypeError("Name must be string");
    this._name = val;
  },
};
person.name;         // "Alice" (calls getter)
person.name = "Bob"; // calls setter

Checking Properties

const obj = { a: 1, b: undefined };

// in operator — checks own + inherited
"a" in obj           // true
"b" in obj           // true (even if undefined)
"toString" in obj    // true (inherited)

// hasOwnProperty — own properties only
obj.hasOwnProperty("a")         // true
obj.hasOwnProperty("toString")  // false

// Object.hasOwn (ES2022 — preferred over hasOwnProperty)
Object.hasOwn(obj, "a")     // true
Object.hasOwn(obj, "b")     // true
Object.hasOwn(obj, "c")     // false

// Existence vs undefined value
"b" in obj           // true  — property exists
obj.b !== undefined  // false — property is undefined
obj.c !== undefined  // false — missing property also undefined

Object Static Methods

Iteration

const obj = { a: 1, b: 2, c: 3 };

Object.keys(obj)    // ["a","b","c"]  (own enumerable keys)
Object.values(obj)  // [1, 2, 3]     (own enumerable values)
Object.entries(obj) // [["a",1],["b",2],["c",3]]

// Iterate
for (const [key, val] of Object.entries(obj)) {
  console.log(key, val);
}

// from entries
Object.fromEntries([["a",1],["b",2]]) // { a: 1, b: 2 }
Object.fromEntries(map)               // Map → object

Copying and Merging

// Object.assign — shallow copy/merge (mutates target)
Object.assign({}, obj)              // copy
Object.assign(target, src1, src2)   // merge into target

// Spread — shallow copy/merge (non-mutating)
const copy = { ...obj };
const merged = { ...defaults, ...overrides };

// Deep clone options
structuredClone(obj)                // ES2022 — deep clone (most types)
JSON.parse(JSON.stringify(obj))     // deep clone (loses functions, undefined, Date becomes string)

Defining and Controlling Properties

// Object.defineProperty — full control over property descriptor
Object.defineProperty(obj, "key", {
  value: 42,
  writable: false,    // can't be reassigned
  enumerable: true,   // shows in for...in, Object.keys
  configurable: false // can't be deleted or redefined
});

Object.defineProperties(obj, {
  x: { value: 1, writable: true, enumerable: true, configurable: true },
  y: { value: 2, writable: true, enumerable: true, configurable: true },
});

// Get descriptor
Object.getOwnPropertyDescriptor(obj, "key");
Object.getOwnPropertyDescriptors(obj);

// All own property names (including non-enumerable)
Object.getOwnPropertyNames(obj);
// Own property Symbols
Object.getOwnPropertySymbols(obj);

Sealing and Freezing

// Object.freeze — no add/delete/modify (shallow)
const frozen = Object.freeze({ a: 1 });
frozen.a = 2;    // silently fails (or TypeError in strict mode)
frozen.b = 3;    // silently fails
Object.isFrozen(frozen); // true

// Object.seal — no add/delete, but can modify values
const sealed = Object.seal({ a: 1 });
sealed.a = 2;    // ok
sealed.b = 3;    // silently fails
Object.isSealed(sealed); // true

// Object.preventExtensions — no new properties
Object.preventExtensions(obj);
Object.isExtensible(obj); // false

Prototype Inspection

Object.getPrototypeOf(obj)         // get prototype
Object.setPrototypeOf(obj, proto)  // set prototype (avoid for perf)
Object.create(proto, descriptors)  // create with prototype
obj instanceof Constructor         // prototype chain check

// Check prototype chain
const arr = [];
arr instanceof Array     // true
arr instanceof Object    // true

Other Static Methods

Object.is(NaN, NaN)     // true  (strict identity, like ===  but NaN-aware)
Object.is(0, -0)        // false (=== returns true)
Object.is(1, 1)         // true

Object.assign(target, ...sources)  // copy enumerable own properties

Computed Keys and Symbol Keys

const prefix = "get";
const sym = Symbol("id");

const api = {
  [`${prefix}Name`]() { return this.name; },  // computed key
  [sym]: 42,                                   // symbol key
};
api.getName();  // works
api[sym];       // 42

// Symbol keys are NOT enumerable by default via Object.keys / for...in
Object.keys(api)             // ["getName"]  (no sym)
Object.getOwnPropertySymbols(api) // [Symbol(id)]

Prototype and Inheritance

function Animal(name) {
  this.name = name;
}
Animal.prototype.speak = function() {
  return `${this.name} makes a noise.`;
};

function Dog(name) {
  Animal.call(this, name); // call super
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function() { return "Woof!"; };

const d = new Dog("Rex");
d.speak(); // inherited
d.bark();

// Modern: use class syntax (see Classes cheatsheet)

Object Patterns

// Namespace / module pattern
const utils = {
  formatDate(date) { return date.toISOString(); },
  parseDate(str)   { return new Date(str); },
};

// Builder pattern
function buildQuery() {
  const params = {};
  return {
    where(key, val) { params[key] = val; return this; },
    limit(n)        { params.limit = n;  return this; },
    build()         { return params; },
  };
}
const q = buildQuery().where("age", 30).limit(10).build();

// Optional properties
const config = {
  host: "localhost",
  ...(process.env.PORT && { port: Number(process.env.PORT) }),
};

// Pick subset of keys
const pick = (obj, keys) =>
  Object.fromEntries(keys.map(k => [k, obj[k]]));

// Omit keys
const omit = (obj, keys) =>
  Object.fromEntries(Object.entries(obj).filter(([k]) => !keys.includes(k)));

// Transform values
const mapValues = (obj, fn) =>
  Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, fn(v)]));

Iteration Patterns

const obj = { a: 1, b: 2, c: 3 };

// Keys
for (const key of Object.keys(obj)) { /* ... */ }

// Values
for (const val of Object.values(obj)) { /* ... */ }

// Entries
for (const [key, val] of Object.entries(obj)) { /* ... */ }

// for...in (includes inherited — usually not what you want)
for (const key in obj) {
  if (Object.hasOwn(obj, key)) { /* own only */ }
}