Chapter 1.4☕ 14 min read

Arrays & Objects — Data Structures

Array ek thela hai, object ek dabba — dono mein data bharo aur kaam karo.

01Array Methods — mutate vs non-mutate

Arrays are ordered, zero-indexed, dynamic-length collections. They're the workhorse of JavaScript data handling.

const chai = ['cutting', 'kadak', 'masala', 'green'];

// Mutating methods (change original)
chai.push('lemon');         // adds to end → length 5
chai.pop();                 // removes from end → 'lemon'
chai.unshift('special');    // adds to start
chai.shift();               // removes from start → 'special'

// Non-mutating methods (return new)
const firstTwo = chai.slice(0, 2); // ['cutting', 'kadak']
console.log(chai);                  // original unchanged

// Searching
console.log(chai.includes('masala')); // true
console.log(chai.indexOf('green'));   // 3
console.log(chai.find(c => c.length > 5)); // 'cutting'
Always know if a method mutates the original or returns a new array. splice() mutates — slice() does not. This distinction matters enormously in Angular where immutability drives change detection.

The length property is not a count of items — it's the highest index + 1. You can set it to truncate: arr.length = 2 removes everything after index 1.

02map, filter, reduce

These three methods are the backbone of functional-style JavaScript. Master them and you'll write cleaner, more predictable code.

const prices = [120, 45, 380, 22, 750, 60];

// map — transform all
const withGST = prices.map(p => p * 1.18);

// filter — keep matching
const affordable = prices.filter(p => p < 100); // [45, 22, 60]

// reduce — accumulate
const total = prices.reduce((sum, p) => sum + p, 0); // 1377

// Chaining — pipeline
const affordableWithGST = prices
  .filter(p => p < 100)
  .map(p => (p * 1.18).toFixed(2));
// ["53.10", "25.96", "70.80"]

// find vs filter
const first = prices.find(p => p > 100);   // 120 (single value)
const all   = prices.filter(p => p > 100); // [120, 380, 750]
📋 Golden Rule:
map, filter, reduce never mutate the original array — they always return a new one. This is why Angular and NgRx love them: pure transformations that don't break change detection.

forEach is for side effects only — it returns undefined. Never use it when you need a result. Use map instead.

03Objects & Destructuring

Objects store key-value pairs. Keys are strings (or Symbols), values can be anything — including other objects and arrays.

const user = {
  name: 'Sai',
  city: 'Hyderabad',
  skills: ['Angular', 'Spring Boot'],
  age: 26,
};

// Dot vs bracket
console.log(user.name);        // 'Sai'
console.log(user['city']);     // 'Hyderabad' — use when key is dynamic

// Destructuring
const { name, city, age = 25 } = user;       // age has default
const { name: devName } = user;               // rename to devName

// Spread — shallow copy & merge
const updated = { ...user, city: 'Mumbai' };  // original unchanged
const merged  = { ...user, role: 'dev' };

// Object.entries() — iterate
Object.entries(user).forEach(([key, val]) => {
  console.log(`${key}: ${val}`);
});
Destructuring in Angular is everywhere — injecting services, reading route params, handling HTTP responses. ({ data, error } = result) is standard Angular pattern.
04Spread, Optional Chaining, Nullish Coalescing

These three operators solve the most common real-world problems in modern JavaScript.

// Spread with arrays
const a = [1, 2, 3];
const b = [4, 5, 6];
const combined = [...a, ...b];        // [1,2,3,4,5,6]
const copy     = [...a];              // shallow copy

// Spread with objects
const defaults = { theme: 'dark', lang: 'en' };
const userPrefs = { lang: 'hyd', fontSize: 16 };
const config = { ...defaults, ...userPrefs };
// { theme: 'dark', lang: 'hyd', fontSize: 16 }

// Optional chaining
const user = null;
console.log(user?.address?.city);     // undefined (no crash!)
console.log(user?.getName?.());       // undefined (method call)

// Nullish coalescing
const port = user?.port ?? 3000;      // 3000 if null/undefined
const name = user?.name ?? 'Guest';   // 'Guest' if null/undefined

// NOT the same as ||
const count = 0 || 10;    // 10 — || treats 0 as falsy
const count2 = 0 ?? 10;   // 0  — ?? only checks null/undefined
📋 Golden Rule:
?. and ?? are your best friends in Angular templates. user?.profile?.avatar ?? 'default.png' — this one line replaces 3 nested if-checks.
05Shallow vs Deep Copy

This is one of the most misunderstood topics in JavaScript — and the source of the nastiest bugs.

// Reference trap
const original = { name: 'Sai', address: { city: 'Hyd' } };
const ref = original;
ref.name = 'Rahul';          // modifies original too!

// Shallow copy — nested still shared
const shallow = { ...original };
shallow.name = 'Kiran';      // ✅ independent
shallow.address.city = 'Mumbai'; // ❌ mutates original.address too!

// Deep copy — fully independent
const deep = structuredClone(original);
deep.address.city = 'Pune';  // ✅ original.address.city still 'Hyd'

// JSON method (old way — loses functions, Date, undefined)
const deepOld = JSON.parse(JSON.stringify(original));

// Angular NgRx pattern — always return new object
function reducer(state, action) {
  return {
    ...state,                          // shallow copy state
    users: [...state.users, action.user] // new array reference
  };
}
Why this matters in Angular: mutating shared object references breaks change detection. If two components share the same object reference and one mutates it, Angular won't detect the change because the reference didn't change — only the contents did.

Lo kar liya — Key Points:

  • ✅ map/filter/reduce never mutate — they return new arrays, keeping Angular change detection happy
  • ✅ Destructuring ({name, city} = user) is standard Angular pattern for services, HTTP, router params
  • ✅ Spread {...obj} creates a shallow copy — nested objects are still shared references
  • ✅ Use structuredClone() for true deep copies; avoid JSON.parse/stringify (loses functions and Dates)
  • ✅ Optional chaining (?.) prevents crashes on null/undefined — essential for Angular SSR code
  • ?? checks only null/undefined; || also triggers on 0, '', false — know the difference
Course Search
Search across all chapters & stages
📖

Search the course

Type any topic — branching, stash, rebase, hooks — and jump straight to that chapter.

merge branchesgit stashundo commitrebase