1.23 — JavaScript Objects: Quick Revision
Compact cheat sheet. Print-friendly.
How to use this material (instructions)
- Skim before labs or interviews.
- Drill gaps — reopen
README.md → 1.23.a…1.23.f.
- Practice —
1.23-Exercise-Questions.md and 1.23.g-Practice-Problems.md.
- Polish answers —
1.23-Interview-Questions.md.
Core vocabulary
| Term | One-liner |
|---|
| Object | Collection of key-value pairs (reference type) |
| Property | A key-value pair on an object |
| Method | A property whose value is a function |
| Key | Always a string or Symbol internally |
| Reference | Variable holds a pointer to the object, not the object itself |
| Shallow copy | New top-level object; nested objects still shared |
| Deep copy | Fully independent clone at every level |
Creating objects
const user = { name: "Alice", age: 25 };
const empty = {};
const name = "Alice";
const obj = { name };
const key = "email";
const obj2 = { [key]: "alice@example.com" };
Accessing properties
| Syntax | When to use |
|---|
obj.key | Static, valid identifier keys (preferred) |
obj["key"] | Dynamic keys, special characters, variables |
obj?.key | Safe access (null/undefined short-circuits) |
obj?.[key] | Safe dynamic access |
obj?.method() | Safe method call |
obj.name
obj["full name"]
obj[variable]
obj?.address?.city
value ?? "default"
?? vs ||
| Value | || treats as falsy | ?? treats as nullish |
|---|
null | Yes | Yes |
undefined | Yes | Yes |
0 | Yes | No |
"" | Yes | No |
false | Yes | No |
Adding, modifying, deleting
obj.newProp = value;
obj["new-prop"] = value;
delete obj.prop;
obj.prop = undefined;
delete vs = undefined
| delete | = undefined |
|---|
"prop" in obj | false | true |
Object.keys | Not listed | Listed |
Property existence checks
"key" in obj
obj.hasOwnProperty("key")
Object.hasOwn(obj, "key")
Copying objects
const shallow = { ...obj };
const shallow2 = Object.assign({}, obj);
const deep = structuredClone(obj);
const legacy = JSON.parse(JSON.stringify(obj));
Shallow vs deep
Shallow: { ...obj }
- Top-level: independent
- Nested: SHARED references
Deep: structuredClone(obj)
- Top-level: independent
- Nested: independent
Non-mutating updates
const updated = { ...obj, key: newValue };
const { removed, ...rest } = obj;
const newState = {
...state,
user: {
...state.user,
address: { ...state.user.address, city: "Seattle" },
},
};
Merging
const merged = { ...defaults, ...overrides };
Object.assign(target, source1, source2);
const merged2 = Object.assign({}, obj1, obj2);
Iterating objects
| Method | Returns | Includes prototype? |
|---|
for...in | Keys (one per loop) | Yes |
Object.keys(obj) | string[] | No |
Object.values(obj) | any[] | No |
Object.entries(obj) | [string, any][] | No |
for (const [key, value] of Object.entries(obj)) {
console.log(key, value);
}
const result = Object.fromEntries(
Object.entries(obj)
.filter(([key, val]) => typeof val === "number")
.map(([key, val]) => [key, val * 2])
);
Property order rules
- Integer-like keys → sorted numerically ascending
- String keys → insertion order
- Symbol keys → insertion order (separate iteration)
Object.keys({ b: 1, a: 2, 2: "x", 1: "y" });
Methods and this
const obj = {
name: "Alice",
greet() {
return `Hi, ${this.name}`;
},
};
obj.greet();
const bad = {
name: "Alice",
greet: () => this.name,
};
Type checks
typeof {}
typeof []
typeof null
typeof function(){}
Array.isArray([])
Array.isArray({})
value !== null && typeof value === "object" && !Array.isArray(value)
Object protection
| Method | Add? | Delete? | Modify? |
|---|
Object.preventExtensions | No | Yes | Yes |
Object.seal | No | No | Yes |
Object.freeze | No | No | No |
All are shallow — nested objects are not affected.
Common patterns
const pick = (obj, keys) =>
Object.fromEntries(Object.entries(obj).filter(([k]) => keys.includes(k)));
const omit = (obj, keys) =>
Object.fromEntries(Object.entries(obj).filter(([k]) => !keys.includes(k)));
const invert = (obj) =>
Object.fromEntries(Object.entries(obj).map(([k, v]) => [v, k]));
const isEmpty = (obj) => Object.keys(obj).length === 0;
const groupBy = (arr, key) =>
arr.reduce((acc, item) => {
(acc[item[key]] ??= []).push(item);
return acc;
}, {});
Master workflow
- Create — object literal
{ key: value } with shorthand where applicable.
- Access — dot for static keys, bracket for dynamic,
?. for safety, ?? for defaults.
- Mutate — direct assignment; use spread for immutable updates.
- Check —
Object.hasOwn(obj, key) for existence.
- Iterate —
Object.entries(obj) + destructuring for key+value loops.
- Copy —
{ ...obj } for shallow, structuredClone(obj) for deep.
- Transform —
entries → map/filter → fromEntries pipeline.
End of 1.23 quick revision.