Excellent — you’re asking the exact right next question. 👏

We’ve already seen that JavaScript non-primitives (also called reference types) behave differently from primitives — now let’s dive deeper into them properly.


⚡ JavaScript Non-Primitive (Reference) Data Types

Non-primitive types are objects or collections — they can hold multiple values, have properties/methods, and are stored by reference (not by value).


🧠 Memory Concept

  • Primitive types: stored directly in stack memory → copied by value
  • Non-primitive types: stored in heap → variable holds a reference (a pointer)
let x = 10;
let y = x;
y = 20;
console.log(x); // 10 (separate copies)

let obj1 = { name: "Rajeev" };
let obj2 = obj1;
obj2.name = "Priya";
console.log(obj1.name); // "Priya" (same object reference)

📦 The Main Non-Primitive Types

CategoryExampleDescription
Object{ key: value }Key-value pairs (core data structure)
Array[1,2,3]Ordered list (special type of object)
Functionfunction() {}Callable object
Datenew Date()Represents date and time
RegExp/abc/Regular expression patterns
Mapnew Map()Key–value store (any type as key)
Setnew Set()Collection of unique values
WeakMap / WeakSetMemory-friendly versions of Map/Set (keys must be objects)

1️⃣ Object

let user = {
  name: "Rajeev",
  age: 30,
  isAdmin: true
};

console.log(user.name);       // Dot notation
console.log(user["age"]);     // Bracket notation

// Add or modify
user.city = "Delhi";
delete user.isAdmin;

🧠 Tip: objects are mutable even if declared with const

const user = { name: "Rajeev" };
user.name = "Priya"; // ✅ works

2️⃣ Array

let fruits = ["apple", "banana", "cherry"];

fruits.push("mango");     // Add to end
fruits.pop();             // Remove from end
console.log(fruits[1]);   // "banana"

for (let fruit of fruits) {
  console.log(fruit);
}

✅ Arrays are technically objects:

console.log(typeof fruits); // "object"

3️⃣ Function

Functions are first-class objects in JS:

  • Can be assigned to variables
  • Passed as arguments
  • Returned from other functions
function greet(name) {
  return "Hello " + name;
}

let sayHi = greet;        // Copy reference
console.log(sayHi("Rajeev"));

4️⃣ Map

Modern key-value structure — allows any type of key.

let userMap = new Map();
userMap.set("name", "Rajeev");
userMap.set(1, "ID 1");
userMap.set({ key: "obj" }, "objectKey");

console.log(userMap.get("name"));
console.log(userMap.size);

✅ Unlike objects, Maps maintain insertion order and do not convert keys to strings.


5️⃣ Set

Collection of unique values.

let ids = new Set([1, 2, 3, 2, 1]);
console.log(ids); // Set(3) {1, 2, 3}

ids.add(4);
ids.delete(2);
console.log(ids.has(3));  // true

6️⃣ Date

let today = new Date();
console.log(today.toDateString());
console.log(today.getFullYear());

7️⃣ RegExp

let pattern = /hello/i;
console.log(pattern.test("Hello world")); // true

8️⃣ WeakMap & WeakSet (Advanced)

  • Keys must be objects.
  • Don’t prevent garbage collection.
  • Useful for storing metadata about objects.
let wm = new WeakMap();
let obj = {};
wm.set(obj, "some data");

⚖️ Comparing Objects

let a = { x: 10 };
let b = { x: 10 };
console.log(a === b); // false (different references)

let c = a;
console.log(a === c); // true

🔍 Summary Table

TypeLiteralKey/ValueOrderDuplicatesExample
Object{}String/Symbol → anyNoYes{a:1}
Array[]Index → anyYesYes[1,2,3]
Functionfunction(){}n/an/an/a()=>{}
Mapnew Map()Any → anyYesYesmap.set('x',10)
Setnew Set()n/aYesNonew Set([1,2,3])

🧩 Mini Practice Challenge

🏗️ “User Directory” using Objects, Arrays, Maps, and Sets

Task:

  1. Create 3 user objects with id, name, email
  2. Store them in:
    • an array
    • a map (key = id, value = user)
    • a set (unique users)
  3. Print:
    • all users
    • all emails
    • check if user with ID=2 exists in the map

✅ Example Output (console)

All users: [ {id:1, name:'Rajeev'}, ... ]
Emails: [ 'r@example.com', 'p@example.com' ]
User 2 exists? true

Would you like me to: