Sitemap

JavaScript Object

4 min readMay 26, 2026

--

(Part 10)

Objects

It is a non-primitive datatype, a dynamic collection of key-value pair, for key only string and symbols are allowed all are converted to strings.

Almost everything in JavaScript is connected to objects:

  • arrays
  • functions
  • classes
  • dates
  • regex
  • maps
  • DOM nodes
  • promises

Even functions themselves are objects.

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

NTERNAL VIEW
user
↓
{
"name" → "Shubham"
"age" → 25
}

Objects are NOT stored directly inside variables The actual object lives in Heap memory while Variables store references to them in Stack.

Stack Memory

user ─────► 0x100


Heap Memory

0x100:
{
name: "Shubham",
age: 25
}

OBJECT CREATION

Objects can be created in multiple ways.

🔥Object Literal Method

const obj = {
x: 10
};

🔥Object Constructor

const obj = new Object();

obj.x = 10;

🔥Object.create

const obj = Object.create(null);

This creates a prototype-less object

🔥Constructor Functions

function User(name) {
this.name = name;
}

const u = new User("A")

🔥Classes

class User {
constructor(name) {
this.name = name;
}
}

const u = new User("A");

//Internally still object-based.

PROPERTY KEYS

Object keys are mostly strings or symbols, any other value is converted to string

const obj = {
1: "one"
};

Internally becomes: "1"
const obj = {};

obj[true] = "yes";

//internally it is obj["true"]
const obj = {};

obj[{}] = "A";

console.log(obj);

//output
{
"[object Object]": "A"
}

hrer {} is converted to string

Normal object property keys are strings internally.

DOT VS BRACKET ACCESS

Dot notation

obj.name

Bracket notation

obj["name"]

Bracket notation evaluates expressions.

const key = "name";

obj[key]
obj["name"]
obj.key
obj["key"]

Trap

const obj = {
name: "Shubham"
};

const key = "name";

console.log(obj.key); //undefined
Because JS literally searches for:"key"

PROPERTY ACCESS ALGORITHM

When you do obj.x, JavaScript internally performs something conceptually like

1. Does obj have property "x"?
2. If yes → return value
3. Else check prototype chain
4. If nowhere found → undefined

Missing properties do NOT throw errors. It returns undefined

const obj = {};

console.log(obj.x); //undefined

OPTIONAL CHAINING

Optional chaining safely stops access. If the left side is null/undefined,
stop evaluation.

obj.x?.y //undefined

OBJECT REFERENCES

Objects are reference types. Assigning objects copies references, not objects.

const a = {
x: 1
};

const b = a;


a ─┐
↓
{ x:1 }
↑
b ─┘

MUTATION

b.x=99

a.x //99

OBJECT EQUALITY

{} === {} //fasle

reference are checked and both have differnt references

{} → address A
{} → address B
const a = {};

const b = a;

a === b //true

SHALLOW COPY

Spread/Object.assign only clone first level. Nested object reference shared.

Spread syntax
const obj1 = {
x: 1
};

const obj2 = {
...obj1
};


//Nested Trap

const a = {
nested: {
x: 1
}
};

const b = { ...a };

b.nested.x = 99;

console.log(a.nested.x); 99

a.nested ─┐
↓
{x:99}
↑
b.nested ─┘

DELETE OPERATOR

delete removes property

const obj = {
x: 1
};

delete obj.x; //Property removed.

ARRAY TRAP

const arr = [1,2,3];

delete arr[1];


[1, empty, 3] creates sparse array hole

PROPERTY EXISTENCE

Checks the property existence, not value. Property exists even if the value is undefined.

"x" in obj  
const obj = {
x: undefined
};

"x" in obj //true

PROPERTY ORDER

const obj = {
2: "b",
1: "a",
x: "x"
};

console.log(Object.keys(obj));
["1", "2", "x"]
1. Integer-like keys
2. String keys (insertion order)
3. Symbols

IMMUTABILITY

Object.freezeThe

const obj = Object.freeze({
x: 1
});

obj.x = 2;


Mutation prevented.

freeze is shallow

const obj = Object.freeze({
nested: {
x: 1
}
});

obj.nested.x = 99;

this works Because nested object not frozen.

INTERNAL PROPERTY DESCRIPTORS

Every property internally has metadata.

{
value,
writable,
enumerable,
configurable
}

ACCESSOR PROPERTY

{
get,
set,
enumerable,
configurable
}

Property descriptor

Object.getOwnPropertyDescriptors tells a description of all the keys inside the object.

let obj={age:12,name:"shubham"};
console.log(Object.c(obj));

// output
{
age: { value: 12, writable: true, enumerable: true, configurable: true },
name: {
value: 'shubham',
writable: true,
enumerable: true,
configurable: true
}
}

console.log(Object.getOwnPropertyDescriptors(obj));

You can see descriptor properties like writable, value, enumerable, and configurable. By default, they are all false, these 4 things are called property descriptors.

Get Shubham Gupta’s stories in your inbox

Join Medium for free to get updates from this writer.

If you use defineProperty, all values are false by default, and if made directly, all are true.

We use object.defineProperty to specify a key property for the object.

let obj={}
Object.defineProperty(obj,"name",{
writable:false
}
obj.name="shubham";
console.log(obj)

Since writable is false, a value can’t be updated

  • value: the value of that property
  • writable: can be edited or not
  • configurable: can be deleted or not
  • enumerable: can be iterated over or not

GETTERS & SETTERS

GETTERS

Getter behaves like property access.

const user = {
first: "Shubham",
last: "Gupta",

get fullName() {
return this.first + " " + this.last;
}
};

user.fullName not user.fullName()

SETTER

const user = {
set age(v) {
console.log("setting", v);
}
};
 ↓
Reference
↓
Heap Object
↓
Properties
↓
Descriptors
↓
Prototype Chain

If you’d like to be in the know, subscribe, clap, like and share. Cheers!

--

--