Lesson 26: Mastering JavaScript Objects basics with challenges!

What are JavaScript Objects?
Objects are dynamic collections of key-value pairs, where:
Keys (aka property names) are always strings or symbols.
Values can be of any type (primitives, objects, functions, etc.).
Objects are non-primitive and mutable. They're used everywhere in JS — from user-defined structures to built-in types like Array
, Date
, Error
, etc.
let user = {
name: "Alice",
age: 28
};
🧱 2. Deep Internal Breakdown
Object Creation:
Literal syntax:
let obj = { key: value };
Constructor:
let obj = new Object();
Accessing / Modifying:
Dot notation:
obj.key
— only works for valid identifiers.Bracket notation:
obj["complex key"]
— supports any string.
Dynamic property names (Computed):
let fruit = "apple";
let bag = {
[fruit]: 5 // same as: bag.apple = 5
};
Shorthand:
let name = "John";
let user = { name }; // same as { name: name }
Property keys:
All keys are strings internally:
let obj = { 1: "a" };
console.log(obj["1"]); // "a"
Special property: __proto__
A getter/setter for the prototype.
Cannot be overwritten by primitives.
obj.__proto__ = 5; // silently ignored
Property Existence:
obj.key === undefined
✅"key" in obj
✅ (even if value isundefined
)
Iteration: for..in
Loops over enumerable own + inherited properties
Key order:
Integer-like keys → sorted numerically.
Others → insertion order.
let obj = { "2": "two", "1": "one" }; // prints 1, 2
🧠 Internal Mechanics
Objects are internally implemented as hash tables (property-key map).
Property lookup time is amortized O(1) unless prototype chains grow deep.
Hidden classes (in V8) optimize repeated object shape usage (same properties in same order) — objects with same “shape” are faster.
💥 Commonly Missed Subtopics & Gotchas
🔸 __proto__
is not just a property
It behaves differently:
obj.__proto__ = null; // modifies prototype chain
If you want to safely add __proto__
as a normal property, use:
Object.create(null)
It creates an object with no prototype.
🔸 Property Enumeration Traps
for..in
iterates enumerable inherited properties, while:
Object.keys()
→ own enumerable propertiesObject.getOwnPropertyNames()
→ own properties (enumerable or not)Reflect.ownKeys()
→ includes symbols
🔸 Numeric vs String keys
let obj = { "1": "a", 1: "b" };
console.log(obj["1"]); // b – overwrites previous value
🔸 Non-Enumerable Properties Are Invisible to for..in
jsCopyEditlet obj = {};
Object.defineProperty(obj, "hidden", {
value: "invisible",
enumerable: false
});
🔸 Don’t Use Objects as Maps!
let map = {};
map["__proto__"] = "bad"; // prototype pollution!
Use Map
if keys are dynamic and may collide with built-ins.
🔸 Functions are Objects too!
function greet() {}
greet.language = "English";
💻 Browser-Specific Quirks
Older IE (≤9) had issues with object enumeration order (non-standard). Modern browsers now follow spec:
Integer-like keys → sorted
Strings → insertion order
⚠️ Developers Often Get Wrong:
Forgetting square brackets for dynamic keys.
Misusing
in
operator vs undefined check.Relying on property order from
for..in
orObject.keys()
without realizing sorting rules.Expecting objects to behave like Maps or arrays.
Trying to delete non-configurable properties.
⚠️ Sub-Concepts Often Missed
✅ 1. Keys are Strings or Symbols — Always
let obj = {};
obj[{}] = "val";
console.log(Object.keys(obj)); // ["[object Object]"]
All non-symbol keys are coerced to strings. Even objects. Only
Symbol()
avoids this.
✅ 2. Own vs Inherited Properties
for..in
includes inherited enumerable props!
const parent = { a: 1 };
const child = Object.create(parent);
child.b = 2;
for (let key in child) console.log(key); // "b", then "a"
✅ 3. Non-Enumerable Props
Object.keys()
skips non-enumerables:
let obj = {};
Object.defineProperty(obj, "hidden", {
value: 123,
enumerable: false
});
console.log(Object.keys(obj)); // []
console.log("hidden" in obj); // true
✅ 4. Object.prototype
Pollution Risk
Object.prototype.foo = 123;
let obj = {};
console.log("foo" in obj); // true — inherited
✅ Solution: Object.create(null)
— a truly blank object without a prototype.
✅ 5. Reserved Keyword Safety (Object Literals)
let obj = {
let: "valid",
return: "also valid"
};
Works fine because property names are always strings in object literals, and reserved keywords aren’t restricted there.
✅ 6. Execution Order Trap: Integer-Like Keys Are Sorted
let obj = {
100: "a",
2: "b",
7: "c"
};
console.log(Object.keys(obj)); // ["2", "7", "100"]
✅ To preserve insertion order, prefix with a character: "id_2"
instead of 2
.
🚨 Dev Confusions & Mistakes
Mistake | Why It’s Problematic |
Using for..in on arrays | Includes inherited props + wrong order |
Assigning to __proto__ | Alters prototype chain |
Using objects for maps | May collide with hasOwnProperty , toString |
Checking key existence with obj[key] === undefined | Fails when value is explicitly undefined |
Using object keys to store functions or DOM nodes | Can lead to memory leaks without proper cleanup |
🔥 3. Challenge Me Deeply
💻 Task 1: Hello, Object
let user = {}; // Create empty object
user.name = "John"; // Add name
user.surname = "Smith"; // Add surname
user.name = "Pete"; // Modify name
delete user.name; // Remove name
💻 Task 2: isEmpty
function isEmpty(obj) {
for (let key in obj) return false;
return true;
}
⚠️
Object.keys(obj).length === 0
is also valid, butfor..in
avoids temporary array allocation.
💻 Task 3: Sum Salaries
let salaries = {
John: 100,
Ann: 160,
Pete: 130
};
let sum = 0;
for (let key in salaries) {
sum += salaries[key];
}
💻 Task 4: Multiply Numeric
function multiplyNumeric(obj) {
for (let key in obj) {
if (typeof obj[key] === "number") {
obj[key] *= 2;
}
}
}
🎯 4. Interview-Ready Questions
✅ Basic
What’s the difference between dot and bracket notation?
Can object keys be non-strings?
What does
__proto__
do, and why is it special?
🧩 Intermediate
Why might
"key" in obj
be better thanobj.key === undefined
?What is the order of keys in
for..in
?What happens when a number is used as a property key?
🧠 Advanced
Why can’t you reliably override
__proto__
with a non-object?How would you deeply clone an object?
Why is it risky to use
for..in
with arrays?What are symbols, and why might you use them as keys?
⚠️ 5. Hidden Pitfalls & Edge Cases
Pitfall | Explanation |
obj["key"] !== undefined | Doesn't guarantee the property exists. It could exist with undefined value. |
__proto__ | Has special prototype-binding behavior, unlike regular keys. |
Integer-like keys | Sorted numerically in for..in . Surprising to many! |
Bracket notation in obj.key | Interprets "key" as a literal property name. Variables must be used like obj[var] . |
Symbol keys | Not accessible via for..in , only via Object.getOwnPropertySymbols() or Reflect.ownKeys() . |
🛠️ 6. Practical Code Patterns
Pattern: Safe property access
if ("key" in obj) {
// do something
}
Pattern: Clone object
let clone = { ...original }; // shallow
Pattern: Count properties
Object.keys(obj).length;
Pattern: Dynamic key assignment
let key = "age";
let obj = { [key]: 30 };
Real-World Usage
💡 In Frameworks:
React props/state: All objects.
Redux store: State trees are plain objects.
Vue reactivity system: Built around property access trapping.
Express.js:
req.params
,res.locals
are object-based.
📦 In Libraries:
Lodash:
_.get
,_.set
,_.has
→ all work with nested object paths.MongoDB: Query filters are objects.
Stripe API, Firebase Config: All config-driven using object literals.
🏭 Production Examples:
User profile objects
Form schema definitions
Config managers
Service maps
Component registries
🔹 6. Remember Like a Pro
🔑 Mnemonic:
DOTS are simple. BRACKETS are powerful.
Dot: Deterministic, Definite, Defined keys
Only identifiers
Tame strings
Short and Sweet
🎯 Cheatsheet (Quick Visual)
Feature | Dot Notation | Bracket Notation |
Works with variable keys | ❌ | ✅ |
Requires valid identifier | ✅ | ❌ |
Allows spaces/symbols | ❌ | ✅ |
🧠 Mind Map (Core Object Concepts)
JavaScript Object
/ | \
Keys Access Tools
/ \ / \ / \
String Symbol Dot Bracket delete/in/for..in
🔹 7. Apply It in a Fun Way
🛠 Mini Project: Dynamic Theme Manager
Build a theme switcher where each theme is stored in an object, and properties are dynamically accessed based on user choice.
🧩 Steps:
Create
themes
object withdark
,light
, andsolarized
keys.Store each theme's colors (bg, text, accent) as nested objects.
Prompt user for theme name → use bracket notation to access theme.
Apply colors to document (in browser or via simulated console log).
Add fallback theme if unknown input is provided.
🧨 Bonus Extensions:
Allow runtime addition of new themes.
Use
Object.keys()
to list available themes.Export/import theme configs via JSON.
🧠 (Optional – Extra Value)
⚙️ Open-Source Projects Using Objects Heavily:
ESLint configs
Babel plugins
Webpack rules/loaders
TailwindCSS theme configuration
🧯 Mistakes Devs Often Make
Modifying inherited props accidentally
Using
delete
in hot code paths (it's slow)Using objects as maps without guarding key collisions
🧩 Performance Tips
Avoid
delete
→ preferobj[key] = undefined
when performance-critical.Use
Map
instead of object if keys are dynamic or non-strings.For nested object access, memoize using tools like Lodash or use structured paths.
Subscribe to my newsletter
Read articles from manoj ymk directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
