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
inoperator vs undefined check.Relying on property order from
for..inorObject.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 === 0is also valid, butfor..inavoids 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 objbe 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..inwith 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.localsare 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
themesobject withdark,light, andsolarizedkeys.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
deletein hot code paths (it's slow)Using objects as maps without guarding key collisions
π§© Performance Tips
Avoid
deleteβ preferobj[key] = undefinedwhen performance-critical.Use
Mapinstead of object if keys are dynamic or non-strings.For nested object access, memoize using tools like Lodash or use structured paths.