JavaScript Interview Prep
Objects & Arrays

Object Static Methods

keys, values, entries, freeze, seal

LinkedIn Hook

Arrays have map, filter, and reduce. Objects have... nothing?

Wrong. Objects have Object.keys, Object.values, and Object.entries — three static methods that let you treat any object as an array-of-something and run the full array toolkit on it. Pair them with Object.fromEntries and you can filter, transform, and rebuild objects in a single chain.

And when you need to lock an object down, the language gives you two dials — Object.freeze (no add, no delete, no modify) and Object.seal (no add, no delete, but existing values can still change). Most developers treat them as the same thing, and most developers are wrong.

There's also the shallow-freeze trap: Object.freeze(config) does not freeze config.database. Nested objects slip right through.

In this lesson you'll master iteration helpers, build a safe deepFreeze, and learn the exact difference between freeze, seal, and an unprotected object.

Read the full lesson -> [link]

#JavaScript #ObjectMethods #Immutability #DeepFreeze #InterviewPrep #Frontend #CodingInterview


Object Static Methods thumbnail


What You'll Learn

  • How Object.keys, Object.values, Object.entries, and Object.fromEntries turn objects into arrays and back
  • The real difference between Object.freeze and Object.seal, including what each blocks
  • The shallow-freeze problem and a recursive deepFreeze that actually locks nested data

The Toolbox Framing

These are your toolbox for working with objects — iterating, inspecting, and protecting them.

Object.keys(), Object.values(), Object.entries()

const product = { name: "Laptop", price: 999, inStock: true };

// keys — array of property names
console.log(Object.keys(product));
// ["name", "price", "inStock"]

// values — array of property values
console.log(Object.values(product));
// ["Laptop", 999, true]

// entries — array of [key, value] pairs
console.log(Object.entries(product));
// [["name", "Laptop"], ["price", 999], ["inStock", true]]

Practical patterns:

const scores = { math: 90, english: 85, science: 92 };

// Convert object to Map
const scoreMap = new Map(Object.entries(scores));

// Filter object properties
const passing = Object.fromEntries(
  Object.entries(scores).filter(([, score]) => score >= 90)
);
console.log(passing); // { math: 90, science: 92 }

// Count properties
console.log(Object.keys(scores).length); // 3

Object.freeze() — Total Lockdown

const config = {
  apiUrl: "https://api.example.com",
  timeout: 5000
};

Object.freeze(config);

config.apiUrl = "https://hacked.com"; // silently fails (throws in strict mode)
config.newProp = "test";              // silently fails
delete config.timeout;                // silently fails

console.log(config.apiUrl); // "https://api.example.com" (unchanged!)
console.log(Object.isFrozen(config)); // true

The Shallow Freeze Problem

const settings = {
  theme: "dark",
  database: {
    host: "localhost",
    port: 5432
  }
};

Object.freeze(settings);

// Top level is frozen
settings.theme = "light"; // fails
console.log(settings.theme); // "dark"

// BUT nested objects are NOT frozen!
settings.database.host = "hacked-server.com"; // THIS WORKS!
console.log(settings.database.host); // "hacked-server.com"

Fix: Deep Freeze

function deepFreeze(obj) {
  Object.freeze(obj);
  Object.keys(obj).forEach(key => {
    const value = obj[key];
    if (typeof value === "object" && value !== null && !Object.isFrozen(value)) {
      deepFreeze(value);
    }
  });
  return obj;
}

const settings = {
  theme: "dark",
  database: { host: "localhost", port: 5432 }
};

deepFreeze(settings);
settings.database.host = "hacked"; // fails now!
console.log(settings.database.host); // "localhost" (protected!)

Object.seal() — No Add/Delete, But Can Modify

const user = { name: "Rakibul", age: 25 };

Object.seal(user);

user.name = "Karim";    // allowed! (modifying existing)
console.log(user.name);  // "Karim"

user.email = "test";     // fails (can't add new)
delete user.age;         // fails (can't delete)

console.log(Object.isSealed(user)); // true

Freeze vs Seal — The Difference

           | Add new | Delete existing | Modify existing |
  freeze   |    X    |       X         |       X         |
  seal     |    X    |       X         |       OK        |
  neither  |   OK    |      OK         |       OK        |

Object Static Methods visual 1


Common Mistakes

  • Treating Object.freeze(config) as bulletproof — nested objects still mutate; you need a recursive deepFreeze for true immutability.
  • Mixing up freeze and seal — seal still allows modifying existing property values; only freeze blocks value changes too.
  • Expecting Object.keys to list inherited or non-enumerable properties — it only returns own enumerable string keys, which is usually what you want but trips up people coming from for...in.

Interview Questions

Q: What is the difference between Object.freeze() and Object.seal()?

freeze prevents adding, deleting, AND modifying properties — total immutability. seal prevents adding and deleting, but existing properties CAN still be modified. Both are shallow.

Q: How do you deep freeze an object?

Write a recursive function that calls Object.freeze() on the object and then recursively freezes every nested object property. Check typeof value === "object" and !Object.isFrozen(value) to avoid infinite loops on circular references.

Q: What does Object.fromEntries() do?

It converts an array of [key, value] pairs back into an object — the inverse of Object.entries(). Useful for transforming/filtering objects via entries.

Q: Why is Object.freeze() called "shallow"? How do you fix it?

Because it only freezes the object's own top-level properties; any object held as a value is still mutable through its own reference. Fix it by recursively walking the tree and calling Object.freeze on each nested object (a deepFreeze helper), skipping already-frozen values to avoid cycles.


Quick Reference — Cheat Sheet

OBJECT STATIC METHODS — QUICK MAP

Inspection / iteration:
  Object.keys(obj)       -> ["a", "b"]
  Object.values(obj)     -> [1, 2]
  Object.entries(obj)    -> [["a", 1], ["b", 2]]
  Object.fromEntries(a)  -> rebuilds object from [[k, v], ...]

Immutability dials:
  Object.freeze(obj)     no add, no delete, no modify (shallow)
  Object.seal(obj)       no add, no delete, CAN modify (shallow)
  Object.isFrozen(obj)   -> boolean
  Object.isSealed(obj)   -> boolean

Common pipeline:
  Object.fromEntries(
    Object.entries(obj).filter(([k, v]) => v >= 90)
  )

Rule of thumb:
  Need to iterate an object?   -> entries + map/filter/reduce
  Need true immutability?       -> recursive deepFreeze

Previous: Destructuring -> Unpacking Objects & Arrays Next: map, filter, reduce -> The Array Transformation Trio


This is Lesson 7.4 of the JavaScript Interview Prep Course — 14 chapters, 87 lessons.

On this page